等待和等待在C#5.0异步

roa*_*oul 11 c# asynchronous async-await c#-5.0

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

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

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

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

Rob*_*ean 11

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

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

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

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

  • 实际上,他们在Windows RT中进行了更改,异步操作返回IAsyncOperation对象,以适应非.NET语言。现在,使用任务包装IAsyncOperation对象 (2认同)

cas*_*One 5

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

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

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

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