C# 异步编程:.NET 完整指南

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

C# 异步编程入门



异步编程是现代 C#(.NET)开发中的基础范式,能让您构建响应迅速且性能卓越的应用程序。与同步方法(代码执行会阻塞当前线程直至操作完成)不同,异步代码在等待耗时操作(例如数据库查询、HTTP 调用或文件读取)的结果时,会释放当前线程去执行其他任务。



随着 C# 5.0 中引入 asyncawait 关键字,异步编程不再复杂,变得对每位开发者都触手可及。在本指南中,我们将逐一解析所有关键概念:从 TaskValueTask 的基础知识到错误处理与操作取消。



async/await 与 Task 基础



什么是 Task 与 Task<TResult>



Task 是 TPL(任务并行库)中的核心类型,代表一个异步操作。Task(无返回值)和 Task<TResult>(有返回值)是构建异步代码的基本单元。



// 无返回值的简单异步方法public async Task DoSomethingAsync(){    await Task.Delay(1000);    Console.WriteLine("Done!");}

// 有返回值的异步方法public async Task<int> CalculateSumAsync(int a, int b){ await Task.Delay(500); // 模拟一个耗时操作 return a + b;}


async 和 await 关键字



async 修饰符告诉编译器该方法包含异步代码。await 运算符会暂停方法的执行,直到等待的任务完成,且不会阻塞线程。



public async Task ProcessDataAsync(){    Console.WriteLine("开始处理...");        // 异步等待 —— 线程未被阻塞    string result = await FetchDataFromApiAsync();        Console.WriteLine($"接收到结果: {result}");}


使用 async/await 的规则



  • 不要使用 async void(事件处理程序除外)—— 这会导致异常无法被追踪。
  • 避免阻塞调用(如 .Result.Wait())—— 它们可能导致死锁。
  • 为异步方法命名时添加 "Async" 后缀以保持清晰性。


进阶技巧:ValueTask、CancellationToken 与并发



ValueTask 与 Task 对比



ValueTask 是一种优化方案,适用于异步操作经常同步完成(例如缓存数据)的场景。与引用类型的 Task 不同,ValueTask 是一个结构体,可以减少垃圾回收器的负担。



public ValueTask<int> GetCachedOrFetchAsync(int id){    if (cache.ContainsKey(id))    {        // 同步完成 —— 无内存分配        return new ValueTask<int>(cache[id]);    }    // 异步完成    return new ValueTask<int>(FetchFromDatabaseAsync(id));}


使用 CancellationToken 取消操作



CancellationToken 允许您优雅地中断长时间运行的异步操作。如果方法接受取消令牌,请始终传递它。



public async Task<string> DownloadFileAsync(string url, CancellationToken ct){    using var client = new HttpClient();    var response = await client.GetAsync(url, ct); // 将 ct 传递给 API    return await response.Content.ReadAsStringAsync();}

// 用法var cts = new CancellationTokenSource();cts.CancelAfter(TimeSpan.FromSeconds(5)); // 5 秒超时

try{ string data = await DownloadFileAsync("https://example.com", cts.Tok

博客

书籍推荐