有人可以确认我是否正确理解了 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");

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

最佳答案

总体思路是正确的 - 该方法的其余部分是各种类型的延续。

"fast path" blog post 详细介绍了 async/await 编译器转换的工作原理。

差异,在我的脑海中:
await 关键字还利用了“调度上下文”概念。如果存在,调度上下文是 SynchronizationContext.Current ,回退到 TaskScheduler.Current 。然后在调度上下文上运行延续。因此,更接近的近似值是将 TaskScheduler.FromCurrentSynchronizationContext 传递到 ContinueWith 中,如有必要,返回 TaskScheduler.Current

实际的 async/await 实现是基于模式匹配;它使用“可等待”模式,允许等待除任务之外的其他事情。一些示例是 WinRT 异步 API,一些特殊方法,例如 Yield 、Rx observables 和 special socket awaitables that don't hit the GC as hard 。任务是强大的,但它们并不是唯一的等待对象。

我想到了一个更小的挑剔差异:如果 awaitable 已经完成,那么 async 方法实际上不会在那个时候返回;它同步继续。所以这有点像传递 TaskContinuationOptions.ExecuteSynchronously ,但没有与堆栈相关的问题。

关于c# - Async await 关键字是否等同于 ContinueWith lambda?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/8767218/

10-14 04:14