C#asynchronous – 它是如何工作的?

微软今天(2010年10月28日)发布了Visual StudioasynchronousCTP ,将asyncawait关键字引入到C#/ VB中,用于执行asynchronous方法。

首先,我认为编译器将关键字转换为线程的创build,但是根据白皮书和Anders Hejlsberg的PDC演示 (在31:00),asynchronous操作完全在主线程上发生。

我怎么能在同一个线程上并行执行一个操作? 在技​​术上怎么可能以及在IL中实际翻译的function是什么?

它与C#2.0中的yield return关键字类似。

一个asynchronous方法实际上并不是一个普通的顺序方法。 它被编译成状态机(一个对象),并有一些状态(局部variables被转换成对象的字段)。 两次使用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#中的asynchronous编程模型非常接近F#asynchronous工作stream程(事实上,除了一些技术细节外,本质上是一样的),使用async编写react native的单线程GUI应用程序是一个相当有趣的领域 – 至less我这样想 – 看看这篇文章 (也许我现在应该写一个C#版本:-))。

该翻译类似于迭代器(和yield return ),实际上,可以使用迭代器在C#中实现asynchronous编程。 我刚才写了一篇关于这个文章的文章 – 我认为它仍然可以让你对翻译的工作有一些了解。

我怎么能在同一个线程上并行执行一个操作?

你不能。 asynchronous不是“并行”或“并发” 。 asynchronous可以用并行来实现,也可以不是。 可以通过将工作分解成小块来实现,将每一块工作放在一个队列中,然后在线程碰巧没有做任何事情时执行每一块工作。

我在博客上有一系列的文章,讲述这些东西是如何工作的。 直接关系到这个问题的人可能会在下周四的星期四上升。 看

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

了解详情。

据我所知, asyncawait关键字的作用是,每当async方法使用await关键字时,编译器会将该方法的其余部分转换为在asynchronous操作完成时调度的延续。 这允许async方法立即返回给调用者,并在asynchronous部分完成时恢复工作。

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

正如我所看到的,asynchronous方法的目的不是并行运行大量的代码,而是将asynchronous方法切成许多小块,可以根据需要调用。 关键是编译器将使用任务/连续处理所有复杂的callback连线。 这不仅降低了复杂度,而且允许像传统的同步代码一样写或多或less的asynchronous方法。