等待和等待在C#5.0异步

时间:2012-12-28 05:33:43

标签: c# asynchronous async-await c#-5.0

任务或任务< TResult> object是等待的,所以我们可以在返回值为Task或Task< TResult>的那些上使用await键。 任务或任务< TResult>是最常用的等待物。

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

  1. 它有一个GetAwaiter()方法(实例方法或扩展方法);
  2. 其GetAwaiter()方法返回awaiter。一个物体是一个等待者 如果:
    • 它实现了INotifyCompletion或ICriticalNotifyCompletion  接口;
    • 它有一个IsCompleted,它有一个getter并返回一个布尔值;
    • 它有一个GetResult()方法,它返回void或结果。
  3. 我的问题是为什么微软没有提供限制这些等待对象的界面? 目前实现等待对象的方法有点复杂。

3 个答案:

答案 0 :(得分:11)

最好在Lucian Wischik的博文Why must async methods return Task?

中回答

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

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

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

答案 1 :(得分:4)

这与他们对foreach关键字的处理方式一致(请参阅C# language specification“foreach声明”的第8.8.4节)。

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

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

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

答案 2 :(得分:0)

我认为主要原因是您在第1点中所说的

  

实例方法或扩展方法

简而言之,因为他们想通过定义扩展方法使用户能够使对象等待,因此,即使您不拥有该对象,也可以使它等待。

Checkout this article