【问题标题】:The awaitable and awaiter In C# 5.0 AsynchronousC# 5.0 异步中的 awaitable 和 awaiter
【发布时间】:2012-12-13 10:54:21
【问题描述】:

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

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

  1. 它有一个GetAwaiter()方法(实例方法或扩展方法);
  2. 它的 GetAwaiter() 方法返回一个等待者。对象是等待者 如果:
    • 它实现了 INotifyCompletion 或 ICriticalNotifyCompletion 界面;
    • 它有一个 IsCompleted,它有一个 getter 并返回一个布尔值;
    • 它有一个 GetResult() 方法,该方法返回 void 或结果。

我的问题是,为什么微软没有提供一个接口来约束这些等待对象? 目前实现等待对象的方法有点复杂。

【问题讨论】:

  • 您在问为什么 GetAwaiter 是一个约定而不是 ITask 接口方法?微软在某处回答了这个问题......我希望我能记得在哪里。

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


【解决方案1】:

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

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

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

上面的影响是如此巨大,以至于提供一个接口是没有意义的。

【讨论】:

  • 实际上,他们在 Windows RT 中进行了更改,其中异步操作返回 IAsyncOperation 对象,以适应非 .NET 语言。现在任务用于包装 IAsyncOperation 对象
  • @PanagiotisKanavos Task 等于 IAsyncOperation 但 C# 中的异步操作仍返回 Task。他们在编译时使用元数据来弥合差异。我不是 100% 清楚,但这就是我的理解,所以理论上这意味着你是对的,你是错的 ;)
  • WinRT 没有任务的概念。事实上,即使在 C# 中,您也可以在 返回 taks 的操作上调用 await,只要它返回带有 GetAwaiter 方法的对象即可。当您需要处理返回值本身时,WinRT 中的任务是一个包装器
  • @PanagiotisKanavos 同意,WinRT 没有任务的概念——这是一个 .NET 功能。编译器使用投影将 .NET 内容转换为 WinRT 项。 .NET 也可以等待实现 GetAwaiter 的任何东西(请参阅我发布的链接)
【解决方案2】:

这与他们对foreach 关键字所做的一致(参见C# language specification“foreach 语句”的第 8.8.4 节)。

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

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

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

【讨论】:

    【解决方案3】:

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

    实例方法或扩展方法

    很简单,因为他们希望通过为对象定义扩展方法来使用户能够使对象变为 Awaitable,因此,即使您不拥有该对象,您也可以使对象变为 Awaitable。

    Checkout this article

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-04-08
      • 2011-07-05
      • 2013-02-18
      • 2013-04-15
      • 2011-05-02
      • 2013-01-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多