等待和等待在C#5.0异步

任务或任务对象是等待的,因此我们可以在返回值为Task或Task 的对象上使用await键。 任务或任务是最常用的等待对象。

我们也可以定义我们自己的等待对象。对象应该具有以下资格。

  1. 它有一个GetAwaiter()方法(实例方法或扩展方法);
  2. 它的GetAwaiter()方法返回一个awaiter。 在下列情况下,对象是等待者:
    • 它实现了INotifyCompletion或ICriticalNotifyCompletion接口;
    • 它有一个IsCompleted,它有一个getter并返回一个布尔值;
    • 它有一个GetResult()方法,它返回void或结果。

我的问题是为什么微软没有提供限制这些等待对象的界面? 目前实现等待对象的方法有点复杂。

最好在Lucian Wischik的博客文章中回答为什么异步方法必须返回Task?

总而言之(我不是在博客上发布正义,你应该阅读它),问题是Task已经存在,所以引入一个接口就意味着

  • 所有内部方法都需要更改为接口,这是一个中断更改,因此框架人员几乎不可能自愿地做。
  • 作为一名程序员,你总是需要决定是否要返回Task或界面,这个决定并不重要。
  • 编译器总是需要一个具体的类型,所以即使你从一个方法返回一个接口,它仍然会被编译为Task

上述影响非常大,提供界面没有意义。

这与他们为foreach关键字所做的一致(参见C#语言规范的第8.8.4节“foreach语句”)。

基本上,它是鸭子打字; 如果类型实现了MoveNext方法和Current属性,那么C#编译器需要知道如何遍历对象公开的序列。

这也适用于集合初始值设定项(参见C#语言规范“集合初始化程序”的第7.6.10.3节); 唯一的要求是该类型实现System.Collections.IEnumerable接口并具有Add方法。

也就是说, await关键字只是坚持先前的先例,不需要特定的接口实现(尽管如果你选择使用它们,接口会提供这些方法),只是编译器可以识别的方法模式。