c# - 异步在 C# 中是如何工作的?

标签 c# .net vb.net asynchronous async-await

Microsoft 宣布 Visual Studio Async CTP今天(2010 年 10 月 28 日)将 asyncawait 关键字引入 C#/VB 以执行异步方法。

首先我认为编译器将关键字转换为线程的创建,但根据 white paper和 Anders Hejlsberg 的 PDC presentation (在 31:00)异步操作完全发生在主线程上。

如何在同一线程上并行执行一个操作?这在技术上如何可能以及在 IL 中实际翻译的功能是什么?

最佳答案

它的作用类似于 C# 2.0 中的 yield return 关键字。

异步方法实际上不是普通的顺序方法。它被编译成具有某种状态的状态机(一个对象)(局部变量变成了对象的字段)。两次使用 await 之间的每个代码块都是状态机的一个“步骤”。

这意味着当方法启动时,它只运行第一步,然后状态机返回并安排一些要完成的工作——当工作完成后,它将运行状态机的下一步。例如这段代码:

async Task Demo() { 
  var v1 = foo();
  var v2 = await bar();
  more(v1, v2);
}

将被翻译成类似的东西:

class _Demo {
  int _v1, _v2;
  int _state = 0; 
  Task<int> _await1;
  public void Step() {
    switch(this._state) {
    case 0: 
      this._v1 = foo();
      this._await1 = bar();
      // When the async operation completes, it will call this method
      this._state = 1;
      op.SetContinuation(Step);
    case 1:
      this._v2 = this._await1.Result; // Get the result of the operation
      more(this._v1, this._v2);
  }
}

重要的部分是它只是使用 SetContinuation 方法来指定当操作完成时,它应该再次调用 Step 方法(并且该方法知道它应使用 _state 字段运行原始代码的第二位)。您可以轻松想象 SetContinuation 类似于 btn.Click += Step,它将完全在单个线程上运行。

C# 中的异步编程模型与 F# 异步工作流非常接近(事实上,除了一些技术细节外,它本质上是一样的),并使用 async 编写响应式(Reactive)单线程 GUI 应用程序> 是一个非常有趣的领域 - 至少我这么认为 - 例如参见 this article (也许我现在应该写一个 C# 版本 :-))。

翻译类似于迭代器(和yield return),事实上,早先在C#中使用迭代器实现异步编程是可能的。我写了an article about that前一段时间 - 我认为它仍然可以让您了解翻译的工作原理。

关于c# - 异步在 C# 中是如何工作的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4047427/

相关文章:

C# - 如何为 IComparable<T> 类实现多个比较器?

c# - Ko ObservableArray 对象未通过 WebAPI 更新

c# - .Net 中的单元测试属性?

vb.net - 从 VB.NET With block 退出

c# - 将 C# 转换为 VB : New. .. 使用{只读属性}

vb.net - VB 模块中的公共(public)属性 - 跨客户端行为

c# - 如何在 C# 中使用 setter 覆盖 getter-only 属性?

C# : How do I get the actual item clicked from SelectedIndexChanged for a ListView control?

c# - 使用 linq 或 lambda 表达式进行对象分组

c# - 如何限制每段时间的方法使用?