高级异步编程
发表于:2025-09-12 | 分类: Csharp
字数统计: 645 | 阅读时长: 2分钟 | 阅读量:

https://learn.microsoft.com/zh-cn/dotnet/standard/asynchronous-programming-patterns/

概述

C# 提供三种执行异步操作的模式:

  1. 异步编程模型:APM,Asynchronous Programming Model
  2. 基于事件:EAP,Event-based Asynchronous Pattern
  3. 基于任务(推荐):TAP,Task-based Asynchronous Pattern

APM

异步编程模型,.Net 1.0 (2002年),最早的异步模型,基于 IAsyncResult 接口,采用 Begin/End 方法 + 回调方法的模式。

核心特点:

  1. 每个异步操作对应两个方法:BeginXXX(..., AsyncCallback callback, object state)EndXXX(IAsyncResult result)
  2. 通过 BeginXXX 启动异步操作,操作完成后自动调用 AsyncCallback 回调函数,回调中通过 EndXXX 获取结果。
  3. 依赖 IAsyncResult 跟踪异步操作状态(是否完成,结果存储等)。

例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// 对应同步方法:Read
// 异步方法对:BeginRead + EndRead
var buffer = new byte[1024];
var fs = new FileStream("file.txt", FileMode.Open);

fs.BeginRead(buffer, 0, buffer.Length, OnReadCompleted, new object[] { fs, buffer });

void OnReadCompleted(IAsyncResult ar) {
var state = (object[])ar.AsyncState;
var fs = (FileStream)state[0];
var buf = (byte[])state[1];

int bytesRead = fs.EndRead(ar);
Console.WriteLine($"读取了 {bytesRead} 字节");
fs.Close();
}

缺点:

  1. 代码分散(启动和回调分离),尤其多步异步操作时会形成回调地狱(嵌套多层回调)。
  2. 需要手动管理异步状态(如通过 AsyncState 传递上下文)。

EAP

基于 事件 的异步模式,.Net 2.0 (2005年),为解决 APM 的回调分散问题,EAP 将异步操作封装为 XXXAsync 方法 + XXXCompleted 事件。

核心特点:

  1. 异步操作通过 XXXAsync 方法启动(如 WebClient.DownloadStringAsync)。
  2. 异步操作完成 / 出错时,触发 XXXCompleted 事件(如 DownloadStringCompleted),在事件处理器中处理结果。
  3. 无需手动传递状态,事件参数(如 AsyncCompletedEventArgs)会携带结果和异常信息。

例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
var client = new WebClient();

// 注册完成事件处理器
client.DownloadStringCompleted += (sender, e) => {
if (e.Error == null) {
Console.WriteLine($"下载内容:{e.Result}");
} else {
Console.WriteLine($"错误:{e.Error.Message}");
}
};

// 启动异步下载
client.DownloadStringAsync(new Uri("https://example.com"));

优点:

  1. 相比 APM ,代码更集中(事件处理器中统一处理结果),减少嵌套。
  2. 自动传递上下文(如异常、取消状态),无需手动管理 IAsyncResult

缺点:

  1. 仍需依赖事件和回调,多步异步操作时仍会出现 “事件嵌套”(如 “下载完成后解析,解析完成后保存” 需嵌套多个事件)。
  2. 不支持 try/catch 直接捕获异常(需在事件参数中判断 e.Error),不符合同步代码的异常处理习惯。

TAP

基于 Task 的异步模式,.Net 4.0 (2010年),引入 TaskTask<TResult> 类型。

上一篇:
Api优化
下一篇:
深入异步编程