Async等待关键字等同于ContinueWith lambda吗?

时间:2012-01-07 03:53:28

标签: c# async-await continuations async-ctp

请有人能够确认我是否正确理解了Async await关键字吗? (使用CTP的第3版)

到目前为止,我已经得出结论,在方法调用之前插入await关键字基本上会做两件事,A。它创建一个立即返回和B.它创建一个“延续”,在异步方法完成时调用调用。在任何情况下,continuation都是该方法的代码块的其余部分。

所以我想知道的是,这两位代码在技术上是等价的,如果是这样,这基本上意味着await关键字与创建ContinueWith Lambda相同(即:它基本上是一个编译器快捷方式)?如果没有,有什么区别?

bool Success =
    await new POP3Connector(
        "mail.server.com", txtUsername.Text, txtPassword.Text).Connect();
// At this point the method will return and following code will
// only be invoked when the operation is complete(?)
MessageBox.Show(Success ? "Logged In" : "Wrong password");

VS

(new POP3Connector(
    "mail.server.com", txtUsername.Text, txtPassword.Text ).Connect())
.ContinueWith((success) =>
    MessageBox.Show(success.Result ? "Logged In" : "Wrong password"));

2 个答案:

答案 0 :(得分:80)

一般的想法是正确的 - 方法的其余部分被制成各种各样的继续。

"fast path" blog post详细介绍了async / await编译器转换的工作原理。

差异,脱离我的头脑:

await关键字也使用“调度上下文”概念。如果存在,则调度上下文为SynchronizationContext.Current,返回TaskScheduler.Current。然后在调度上下文上运行继续。因此,更近似的是将TaskScheduler.FromCurrentSynchronizationContext传递到ContinueWith,如有必要,请回到TaskScheduler.Current

实际的async / await实施基于模式匹配;它使用“等待”模式,允许等待除任务之外的其他事物。一些示例是WinRT异步API,一些特殊方法,如Yield,Rx observables和special socket awaitables that don't hit the GC as hard。任务是强大的,但他们不是唯一的等待。

另一个小的挑剔的区别在于:如果等待已经完成,那么async方法实际上并不会在那时返回;它继续同步。所以它有点像传递TaskContinuationOptions.ExecuteSynchronously,但没有与堆栈相关的问题。

答案 1 :(得分:8)

它本质上是“基本上”,但生成的代码确实不仅仅是这样。有关生成代码的更多详细信息,我强烈推荐Jon Skeet的Eduasync系列:

http://codeblog.jonskeet.uk/category/eduasync/

特别是,第7篇文章会进入生成的内容(从CTP 2开始)及其原因,所以可能非常适合您目前正在寻找的内容:

http://codeblog.jonskeet.uk/2011/05/20/eduasync-part-7-generated-code-from-a-simple-async-method/

编辑:我认为它可能比你在问题中寻找的更详细,但是如果你想知道当你在方法中有多个等待时会发生什么样的事情,那就在第9篇文章中有所介绍: )

http://codeblog.jonskeet.uk/2011/05/30/eduasync-part-9-generated-code-for-multiple-awaits/