微软宣布 Visual Studio 异步 CTP 今天(2010 年 10 月 28 日)介绍 asyncawait C#/VB 中的关键字用于异步方法执行。

首先我认为编译器将关键字翻译为线程的创建,但根据 白皮书 和安德斯·海尔斯伯格的 PDC演示 (31:00)异步操作完全发生在主线程上。

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

有帮助吗?

解决方案

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

异步方法实际上并不是普通的顺序方法。它被编译成具有某种状态的状态机(对象)(局部变量被转换为对象的字段)。两次使用之间的每个代码块 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# 异步工作流程(事实上,除了一些技术细节之外,本质上是同一件事),并且使用以下代码编写反应式单线程 GUI 应用程序 async 是一个非常有趣的领域 - 至少我这么认为 - 例如参见 本文 (也许我现在应该写一个 C# 版本:-))。

翻译类似于迭代器(和 yield return)而且事实上,很早以前在 C# 中就可以使用迭代器来实现异步编程。我写 一篇关于那个的文章 不久前 - 我认为它仍然可以让您了解翻译的工作原理。

其他提示

如何在同一线程上并行执行操作?

你不能。 异步不是“并行”或“并发”. 。异步可能通过并行性来实现,也可能不是。它可以通过以下方式实现:将工作分解为小块,将每个工作块放入队列中,然后在线程碰巧没有执行任何其他操作时执行每个工作块。

我的博客上有一系列关于所有这些东西如何工作的文章;与这个问题直接相关的问题可能会在下周四出现。手表

http://blogs.msdn.com/b/ericlippert/archive/tags/async/

了解详情。

据我了解,什么是 asyncawait 关键字所做的是每次 async 方法采用 await 关键字,编译器会将方法的其余部分转换为异步操作完成时安排的延续。这允许 async 方法立即返回调用者并在异步部分完成后恢复工作。

根据现有的文件,有很多细节,但除非我弄错了,这就是它的要点。

在我看来,异步方法的目的不是并行运行大量代码,而是将异步方法分成许多小块,可以根据需要调用。关键点是编译器将使用任务/延续处理回调的所有复杂连接。这不仅降低了复杂性,而且允许异步方法或多或少像传统同步代码一样编写。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top