Dir*_*mar 47 .net c# vb.net asynchronous async-await
微软今天(2010年10月28日)宣布推出Visual Studio Async CTP,它将async和await关键字引入C#/ VB以实现异步方法.
首先,我认为编译器将关键字转换为线程的创建,但根据白皮书和Anders Hejlsberg的PDC演示文稿(在31:00),异步操作完全在主线程上发生.
如何在同一个线程上并行执行操作?在技术上如何可能以及在IL中实际翻译的功能是什么?
Tom*_*cek 81
它的工作方式与yield returnC#2.0中的关键字类似.
异步方法实际上不是普通的顺序方法.它被编译成具有某种状态的状态机(对象)(局部变量被转换为对象的字段).两次使用之间的每个代码块await是状态机的一个"步骤".
这意味着当方法启动时,它只运行第一步,然后状态机返回并安排一些工作要完成 - 当工作完成时,它将运行状态机的下一步.例如这段代码:
async Task Demo() {
var v1 = foo();
var v2 = await bar();
more(v1, v2);
}
Run Code Online (Sandbox Code Playgroud)
会被翻译成:
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);
}
}
Run Code Online (Sandbox Code Playgroud)
最重要的部分是,它只是使用的SetContinuation方法来指定操作完成时,应该调用Step再次方法(和方法知道它应该使用运行原始代码的第二位_state字段).你可以很容易地想象它SetContinuation会像是一样btn.Click += Step,完全在一个线程上运行.
C#中的异步编程模型是非常接近的F#异步工作流(事实上,它在本质上是一样的东西,除了一些技术细节),并写入使用反应单线程GUI应用程序async是一个非常有趣的领域-至少我认为所以 - 比如看看这篇文章(也许我现在应该写一个C#版本:-)).
转换类似于迭代器(和yield return),实际上,可以使用迭代器在C#中实现异步编程.我刚刚写了一篇关于这篇文章的文章 - 我认为它仍然能让你对翻译的工作原理有所了解.
Eri*_*ert 46
如何在同一个线程上并行执行操作?
你不能.异步不是"并行"或"并发".异步可能是以并行性实现的,也可能不是.它可以通过将工作分解成小块,将每个工作块放在队列上,然后在线程碰巧没有做任何事情时执行每个工作块来实现.
我的博客上有一系列关于这些东西是如何工作的文章; 与这个问题直接密切相关的人可能会在下周四上升.看
http://blogs.msdn.com/b/ericlippert/archive/tags/async/
详情.
据我了解,关键字async和await关键字的作用是每次async方法使用await关键字时,编译器会将方法的其余部分转换为异步操作完成时调度的延续.这允许async方法立即返回调用方并在异步部分完成时恢复工作.
根据现有的论文,它有很多细节,但除非我弄错了,这就是它的要点.
正如我所看到的,异步方法的目的不是并行运行大量代码,而是将异步方法分成许多小块,可以根据需要调用.关键是编译器将使用任务/继续处理所有复杂的回调连接.这不仅降低了复杂性,而且允许异步方法或多或少地像传统的同步代码一样编写.