Async是否等待关键字等同于ContinueWith lambda?
有人可以请客气一点,以确认我是否已经正确理解了异步关键字? (使用CTP的第3版)
到目前为止,我已经计算出,在方法调用之前插入await关键字本质上是做了两件事,它创建了一个立即返回值和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"));
总的想法是正确的 - 该方法的其余部分被做成各种各样的延续。
“快速路径”博客文章详细介绍了async
/ await
编译器转换的工作方式。
差异,我的头顶:
await
关键字也使用“调度上下文”概念。 如果调度上下文存在,则调度上下文为SynchronizationContext.Current
,并回退到TaskScheduler.Current
。 然后继续在调度上下文中运行。 因此,更近似的方法是将TaskScheduler.FromCurrentSynchronizationContext
传递到ContinueWith
,如有必要,返回TaskScheduler.Current
。
实际的async
/ await
实现基于模式匹配; 它使用“等待”模式,允许等待除了任务之外的其他事情。 一些例子是WinRT异步API,一些特殊的方法,如Yield
,Rx observables和特殊的套接字awaitables,它们并没有像GC那样击中GC。 任务是强大的,但他们不是唯一的候选人。
想到另一个微小的挑剔的区别:如果awaitable已经完成,那么async
方法实际上并不会在这一点上返回; 它继续同步。 所以它就像传递TaskContinuationOptions.ExecuteSynchronously
,但没有堆栈相关的问题。
这是“本质上”的,但生成的代码不仅仅是这些。 有关代码生成的更多细节,我强烈推荐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/
链接地址: http://www.djcxy.com/p/53249.html上一篇: Is Async await keyword equivalent to a ContinueWith lambda?