Async await关键字是否等效于ContinueWith lambda

本文关键字:ContinueWith lambda await 关键字 是否 Async | 更新日期: 2023-09-27 18:19:37

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

到目前为止,我已经计算出在方法调用之前插入wait关键字本质上可以做两件事,a。它创建一个立即返回;"延续";在异步方法调用完成时调用。在任何情况下,延续都是该方法的代码块的剩余部分。

所以我想知道的是,这两位代码在技术上是等效的吗?如果是,这是否基本上意味着wait关键字与创建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");

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

Async await关键字是否等效于ContinueWith lambda

总的想法是正确的-方法的剩余部分被做成排序的延续。

"快速路径"博客文章详细介绍了async/await编译器转换的工作原理。

差异,我脑海中浮现:

await关键字还使用了"调度上下文"概念。调度上下文是SynchronizationContext.Current(如果存在的话),回退到TaskScheduler.Current。然后在调度上下文上运行延续。因此,一个更接近的近似值是将TaskScheduler.FromCurrentSynchronizationContext传递到ContinueWith,必要时回退到TaskScheduler.Current

实际的async/await实现是基于模式匹配的;它使用了一种"awaitable"模式,允许等待任务之外的其他事情。一些例子是WinRT异步API,一些特殊的方法,如Yield、Rx可观察性,以及对GC没有那么严重影响的特殊套接字可用性。任务是强大的,但它们并不是唯一可获得的。

脑海中浮现出一个更细微的区别:如果awaitable已经完成,那么async方法在那一点上实际上不会返回;它同步地继续。所以这有点像传递TaskContinuationOptions.ExecuteSynchronously,但没有与堆栈相关的问题。

这"本质上"是这样,但生成的代码严格意义上不仅仅是这样。关于生成的代码的更多细节,我强烈推荐Jon Skeet的Eduasync系列:

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

特别是,第7篇文章深入探讨了生成的内容(截至CTP2)及其原因,因此可能非常适合您目前正在寻找的内容:

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/