等待最后一次异步调用和返回它之间有区别吗?

时间:2017-05-04 09:52:38

标签: c# async-await

见问题标题。

换句话说,给定一种方法

async Task FrobnicateAsync() { ... }

之间是否存在任何(可能是微妙的)差异
async Task FrobAndFrobnicateAsync()
{
    Frob();
    await FrobnicateAsync();
}

Task FrobAndFrobnicateAsync()
{
    Frob();
    return FrobnicateAsync();
}

2 个答案:

答案 0 :(得分:2)

如果字面显示代码,那么您应该更喜欢return FrobnicateAsync()版本 - 它避免了额外的状态机抽象层,而且效率更高。

如果您有其他内容 - 特别是围绕 finally的任何using(包括return)代码,则您必须确保使用await版本,这样finally代码才会在<{em> {/ 1>} async任务完成后才会发生。

如有疑问,请使用async / await版本。

好消息是:它不会影响签名(因此不是一个重大变化)在它们之间切换,因此您现在可以更有效的方式实现它,并更改为async / {{ 1}}如果您发现以后需要添加await块。

另外一个想法是:如果通常期望它同步完成,那么你可能会更加微妙:

using

这可以避免状态机 在不需要时

答案 1 :(得分:2)

我在eliding async上有一篇博文。

由于您在Frob之前有一个非平凡的await,我建议您保持 asyncawait。这种方法的好处是:

  • 如果没有asyncFrob抛出异常,则会直接抛出异常,这对消费者来说是一种令人惊讶的行为。即使Frob今天没有例外,明年也可以这样做;因此await的代码更易于维护。
  • 如果没有async,那么FrobFrobnicateAsync在同一逻辑调用上下文中不存在(假设它实际上是async);相反,它将存在于与FrobAndFrobnicateAsync的调用者相同的逻辑调用上下文中。这在大多数代码中都不是问题。

另见What Is the Purpose of return await?