.NET 支持三个异步编程模式:
-
异步编程模型 (APM)(旧版)
-
基于事件的异步模式 (EAP)(旧版)
-
基于任务的异步模式 (TAP)(建议用于新开发)
Read 方法的异步版本。
每次调用 BeginOperationName 时,应用程序还应调用 EndOperationName 来获取操作的结果。
此对象可用来向异步操作完成时调用的方法传递应用程序特定的状态信息。
IAsyncResult 对象表示的异步操作尚未完成,则 EndOperationName 将在异步操作完成之前阻止调用线程。
若要在异步操作完成之前阻止应用程序,可以使用下列方法之一:
- 从应用程序的主线程调用
EndOperationName,阻止应用程序执行,直到操作完成之后再继续执行。 - AsyncWaitHandle 来阻止应用程序执行,直到一个或多个操作完成。result.AsyncWaitHandle.WaitOne();
在异步操作完成时不需要阻止的应用程序可使用下列方法之一:
-
轮询异步操作的状态。
-
使用 AsyncCallback 委托结束异步操作。
基于事件的异步模式 (EAP)
那些同时执行多项任务、但仍能响应用户交互的应用程序通常需要实施一种使用多线程的设计方案。
对于更复杂的异步应用程序,请考虑实现一个符合基于事件的异步模式的类。
PictureBox 是一个支持基于事件的异步模式的典型组件。
基于任务的异步模式 (TAP)
基于任务的异步模式 (TAP) 使用单个方法表示异步操作的开始和完成。
生成 TAP 方法
使用编译器
任何归于 async 关键字的方法都被视为异步方法。
手动生成 TAP 方法
SetCanceled 方法,或调用这些方法之一的Try版本。
public static Task<int> ReadTask(this Stream stream, byte[] buffer, int offset, int count, object state)
{
var tcs = new TaskCompletionSource<int>();
stream.BeginRead(buffer, offset, count, ar =>
{
try { tcs.SetResult(stream.EndRead(ar)); }
catch (Exception exc) { tcs.SetException(exc); }
}, state);
return tcs.Task;
}
工作负载
如果方法是 I/O 密集型,应只公开为异步实现。
计算密集型任务
ThreadPool 类中的特殊支持来提供有效的执行,还对执行异步计算的时间、地点和方式提供重要控制。
通过以下方式生成计算密集型任务:
- Func<TResult>)。
- TaskFactory.StartNew 的快捷方式。
- 想要分别生成并计划任务时,请使用
Task类型或Start方法的构造函数。 - 使用 Task.ContinueWith 方法的重载。
- TaskFactory.ContinueWhenAny 方法。
I/O 密集型任务
SetCanceled 以及它们的 TrySet 变形。
计算密集型和 I/O 密集型混合任务
异步方法不只局限于计算密集型或 I/O 密集型操作,还可以是两者的结合。