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

Max*_*ich 79 c# continuations async-await 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");
Run Code Online (Sandbox Code Playgroud)

VS

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

Ste*_*ary 81

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

"快速通道"的博客文章对如何详细信息async/ await编译器改造工作.

差异,脱离我的头脑:

await关键字还使用"调度上下文"概念.调度上下文SynchronizationContext.Current是否存在,重新开始TaskScheduler.Current.然后在调度上下文上运行继续.因此,一个更接近于将传递TaskScheduler.FromCurrentSynchronizationContextContinueWith上回落TaskScheduler.Current,如果必要的.

实际async/ await实现基于模式匹配; 它使用"等待"模式,允许等待除任务之外的其他事物.一些例子是WinRT异步API,一些特殊的方法,如YieldRx observables,以及特殊的socket等待,它们没有像GC那样严重打击GC.任务是强大的,但他们不是唯一的等待.

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

  • 另一个async/await比ContinueWith(...)更具表现力的例子是异常流动.您可以在同一个try块中多次等待,并且对于每个执行阶段,它们的异常可以汇集到相同的catch(...)块,而无需编写大量明确执行此操作的代码. (7认同)
  • 斯蒂芬在这里的位置.对于简单的示例,很容易认为async/await只是ContinueWith的快捷方式 - 但是,我喜欢反过来考虑它.Async/await实际上是您使用ContinueWith的更强大的表达式.问题是ContinueWith(...)使用lambdas,并允许执行转移到continuation,但是如果你必须在ContinueWith之前放置一半循环体,那么其他控制流概念(如循环)是非常不可能的. .)和另一半之后.您最终会手动连续链接. (4认同)
  • 很好地说 - 我试着推迟Jon的帖子,因为它们比我有时间在SO上回答的任何事情都要广泛得多,但Stephen绝对正确.WRT什么是等待的(尤其是GetAwaiter),他的帖子#3非常有帮助恕我直言:) http://msmvps.com/blogs/jon_skeet/archive/2011/05/13/eduasync-part-3-the-shape-的最异步-方法-awaitable-boundary.aspx (2认同)
  • async/await的最后一部分值得注意的是它是一个"更高级别的概念",而ContinueWith(...)更加手动,并且明确地具有lambdas,委托创建等.对于更高级别的概念,有更多的优化机会 - 所以对于例如,多个等待在同一个方法中实际上"共享"相同的lambda闭包(它就像一个lambda的开销),而ContinueWith(...)每次调用它时都会获得开销,因为你明确写了一个lambda,所以编译器会给你. (2认同)

Jam*_*ing 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/