【问题标题】:Async/Await Execution Difference异步/等待执行差异
【发布时间】:2014-04-20 10:17:04
【问题描述】:

我正在尝试很好地掌握 async/await 并且我想消除一些困惑。有人可以解释一下在执行方面有什么不同:

// version 1
public Task Copy(string source, string destination) {
    return Task.Run(() => File.Copy(source, destination));
}

public async Task Test() {
    await Copy("test", "test2");    
    // do other stuff
}

还有:

// version 2
public async Task Copy(string source, string destination) {
    await Task.Run(() => File.Copy(source, destination));
}

public async Task Test() {
    await Copy("test", "test2");
    // ...
}

它们会产生相同的代码吗?为什么我要写一个而不是另一个?

【问题讨论】:

  • @Noseratio 是的,确实如此,Erics 的回答也是一个“大开眼界”,对不起,没有找到任何东西(不确定如何制定搜索:P)
  • @DimitarDimitrov,IMO,除了状态机的开销,最主要的区别是exception propagation logic
  • @Noseratio 谢谢!极好的答案(你链接的那个)。这很有帮助!

标签: c# asynchronous async-await


【解决方案1】:

首先让我从两个代码相同的观点开始。

您的 version1 代码将仅创建一个“状态机”,因为它仅在 Test 方法中包含 await。

您的 version2 代码将为 CopyTest 方法创建两个“状态机”,这会增加一些开销。

为什么我们使用async 方法?简单只是为了让我们的代码在处理“异步任务”时可读、优雅。它使我们的代码更好地避免回调和延续等。

让我们分解Copy 方法的作用,然后我们回答 质疑我们是否真的需要async

Copy 方法只是将调用委托给Task.Run,它返回一个最终在File.Copy 完成时完成的任务。所以这里的意图很清楚,我们需要一个通知File.Copy完成的任务。此方法可以满足您的所有需求,无需 async 即可按预期工作。

那么,你什么时候需要async

当您需要在早期任务完成(继续)时执行一些代码时,您需要异步。

例子:

public async Task Test() 
{
    await Copy("test", "test2");
    DoPostCopied(whatever);
    await DoPostCopied2();//Etc
}

您可以通过反编译两个版本来验证async 和非异步方法之间的这种差异。它太长而且不可读,所以我跳过在这里发布它。

结论:仅在需要时使用async。在这种情况下,版本 1 更好,您应该更喜欢版本 2。

【讨论】:

  • @AmitJoki 我想我们需要为 op 以及有趣的问题提供 +1
  • 谢谢,很清楚! :) 所以基本上只有当你必须时才异步
  • @DimitarDimitrov 是的,就是这样。 Bonus reading 关于异步等待开销 :)
猜你喜欢
  • 2015-01-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-09-30
  • 2023-03-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多