基于Task的异步模式(TAP)是微软推荐的一系列使用Task类型编写异步API的方式。微软的并行编程小组的成员Stephen Toub写了一篇文章,其中有一些很棒的例子,值得一读。
使用async关键字来产生遵循此模式的方法,需要使用await进行调用。通常来说,以手动的方式使用Task类型很有帮助。在本章中,我将介绍这个模式,以及使用它的一些技巧。
TAP约定了什么
假定我们已经知道了如何来设计良好的C#同步方法签名:
- 应该包含较少的参数,或者不使用参数。尽量避免使用ref和out参数。
- 如果需要,应该包含返回类型,并且返回类型要能够真实表达方法需要的返回结果,而不是像一些C++方法那样,返回一个标识成功或者失败的值。
- 应该使用可以明确阐明方法行为的名字,无需使用额外的注释。
- 通常情况或者预期的失败都应该是返回类型的一种情况,但是非预期的错误应该抛异常
下面是一个设计得比较好的同步方法,它位于Dns类中
public static IPHostEntry GetHostEntry(string hostNameOrAddress)
基于你已有的同步方法的技巧,TAP针对异步方法给予了类似的指导:
- 与同步方法相对应的异步方法应该包含相同的参数。永远不要使用ref和out参数。
- 方法应该返回Task或者Task<T>,具体返回哪一个应该取决于异步方法是否含有返回类型。任务应该在将来的某一时刻结束,同时提供方法的结果值。
- 应该命名为NameAsync,其中Name是对应的同步方法的名称。
- 由方法使用错误导致的异常可能会直接从方法中抛出。任何其它的异常应该被放在Task中。
下面是一个设计得比较好的异步方法:
public static Task<IPHostEntry> GetHostEntryAsync(string hostNameOrAddress)
这看起来无需多讲,但是正如我们在第3章 .NET中采用的异步模式 所讲的那样,TAP是.NET framework中正式使用的异步模式。我敢说其他人肯定曾经使用过无数不正规的方式来书写异步代码。
TAP的核心思想是:针对异步方法会返回一个Task,它会确保耗时的操作在将来能够结束。如果不采用这种方式,之前说的异步模式要么需要在方法上添加额外的参数,要么需要在接口上添加额外的方法或者事件来支持回调机制。Task包括了支持回调所需的所有“基础设施”,同时使用Task还