提问人:Maxim Gershkovich 提问时间:1/7/2012 最后编辑:David KlempfnerMaxim Gershkovich 更新时间:9/14/2021 访问量:22113
Async await 关键字是否等同于 ContinueWith lambda?
Is Async await keyword equivalent to a ContinueWith lambda?
问:
有人可以确认我是否正确理解了 Async await 关键字吗?(使用CTP第3版)
到目前为止,我已经发现在方法调用之前插入 await 关键字基本上可以做两件事,A。它创造了一个即时的回报和B。它创建一个“延续”,在异步方法调用完成后调用该“延续”。在任何情况下,延续都是该方法代码块的其余部分。
所以我想知道的是,这两段代码在技术上是否等效,如果是这样,这是否意味着 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");
与
(new POP3Connector(
"mail.server.com", txtUsername.Text, txtPassword.Text ).Connect())
.ContinueWith((success) =>
MessageBox.Show(success.Result ? "Logged In" : "Wrong password"));
答:
“本质上”就是这样,但生成的代码严格来说远不止于此。有关生成的代码的更多详细信息,我强烈推荐 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/
总体思路是正确的 - 该方法的其余部分被制成各种延续。
“快速路径”博客文章详细介绍了 / 编译器转换的工作原理。async
await
差异,从我的头顶:
该关键字还使用了“调度上下文”概念。调度上下文是 如果存在,则回退到 。然后,在调度上下文上运行延续。因此,更接近的近似值是传递到 ,必要时回退。await
SynchronizationContext.Current
TaskScheduler.Current
TaskScheduler.FromCurrentSynchronizationContext
ContinueWith
TaskScheduler.Current
实际/实现基于模式匹配;它使用“可等待”模式,允许等待任务以外的其他事情。一些示例包括 WinRT 异步 API、一些特殊方法(如 Rx 可观察对象)和特殊的套接字可调试对象,这些方法不会对 GC 造成太大影响。任务很强大,但它们并不是唯一等待的。async
await
Yield
我想到了一个细微的挑剔差异:如果 awaitable 已经完成,那么该方法实际上不会在此时返回;它同步继续。所以这有点像 pass ,但没有与堆栈相关的问题。async
TaskContinuationOptions.ExecuteSynchronously
评论
await
SynchronizationContext.Current
SynchronizationContext.Current
null
评论