Async wait 关键字是否等同于ContinueWith lambda?
有人可以确认我是否正确理解了 Async wait 关键字吗? (使用 CTP 的版本 3)
到目前为止,我已经发现在方法调用之前插入 wait 关键字本质上会做两件事,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");
VS
(new POP3Connector(
"mail.server.com", txtUsername.Text, txtPassword.Text ).Connect())
.ContinueWith((success) =>
MessageBox.Show(success.Result ? "Logged In" : "Wrong password"));
Could someone please be kind enough to confirm if I have understood the Async await keyword correctly? (Using version 3 of the CTP)
Thus far I have worked out that inserting the await keyword prior to a method call essentially does 2 things, A. It creates an immediate return and B. It creates a "continuation" that is invoked upon the completion of the async method invocation. In any case the continuation is the remainder of the code block for the method.
So what I am wondering is, are these two bits of code technically equivalent, and if so, does this basically mean that the await keyword is identical to creating a ContinueWith Lambda (Ie: it's basically a compiler shortcut for one)? If not, what are the differences?
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"));
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
总体想法是正确的 - 该方法的其余部分被制成某种延续。
“快速路径”博客文章 详细介绍了
async
/await
编译器转换的工作原理。差异,在我的脑海中浮现:
await
关键字还利用了“调度上下文”概念。调度上下文为SynchronizationContext.Current
(如果存在),并依赖于TaskScheduler.Current
。然后,延续在调度上下文上运行。因此,更接近的近似方法是将TaskScheduler.FromCurrentSynchronizationContext
传递到ContinueWith
,如有必要,则返回到TaskScheduler.Current
。实际的
async
/await
实现是基于模式匹配的;它使用“可等待”模式,允许等待任务以外的其他事情。一些示例是 WinRT 异步 API、一些特殊方法,例如Yield
、Rx 可观察对象和 特殊套接字等待,不会对 GC 产生太大影响。任务很强大,但它们并不是唯一值得等待的事情。我想到了另一个细微的差别:如果等待已经完成,那么 async 方法实际上不会在此时返回;它同步继续。所以这有点像传递TaskContinuationOptions.ExecuteSynchronously,但没有与堆栈相关的问题。
The general idea is correct - the remainder of the method is made into a continuation of sorts.
The "fast path" blog post has details on how the
async
/await
compiler transformation works.Differences, off the top of my head:
The
await
keyword also makes use of a "scheduling context" concept. The scheduling context isSynchronizationContext.Current
if it exists, falling back onTaskScheduler.Current
. The continuation is then run on the scheduling context. So a closer approximation would be to passTaskScheduler.FromCurrentSynchronizationContext
intoContinueWith
, falling back onTaskScheduler.Current
if necessary.The actual
async
/await
implementation is based on pattern matching; it uses an "awaitable" pattern that allows other things besides tasks to be awaited. Some examples are the WinRT asynchronous APIs, some special methods such asYield
, Rx observables, and special socket awaitables that don't hit the GC as hard. Tasks are powerful, but they're not the only awaitables.One more minor nitpicky difference comes to mind: if the awaitable is already completed, then the
async
method does not actually return at that point; it continues synchronously. So it's kind of like passingTaskContinuationOptions.ExecuteSynchronously
, but without the stack-related problems.“本质上”是这样,但生成的代码不仅仅如此。有关生成的代码的更多详细信息,我强烈推荐 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-await/
It's "essentially" that, but the generated code does strictly more than just that. For lots more detail on the code generated, I'd highly recommend Jon Skeet's Eduasync series:
http://codeblog.jonskeet.uk/category/eduasync/
In particular, post #7 gets into what gets generated (as of CTP 2) and why, so probably a great fit for what you're looking for at the moment:
http://codeblog.jonskeet.uk/2011/05/20/eduasync-part-7-generated-code-from-a-simple-async-method/
EDIT: I think it's likely to be more detail than what you're looking for from the question, but if you're wondering what things look like when you have multiple awaits in the method, that's covered in post #9 :)
http://codeblog.jonskeet.uk/2011/05/30/eduasync-part-9-generated-code-for-multiple-awaits/