等待任务:如果await后没有代码,则返回任务或等待。

19

我已经阅读了一些内容,认为我掌握了关于System.Threading.Task的await和async关键字的基础知识。

然而,有一个小问题我不确定是否正确,我希望找人验证或指正。

我正在实现一个带有如下签名的异步方法:

public Task ProcessUploadedFile(FileInfo info, string contentType);

显然,如果我想在方法内等待任何东西,我需要将async关键字添加到签名中。

我的问题是:如果我的方法最后要做的事情是调用另一个异步方法或返回一个任务,那么有必要等待它吗?

例如:

1:

public async Task ProcessUploadedFile(FileInfo info, string contentType)
{
  foreach (var something in someCollection)
    DoSomething();

  DoSomethingElse();

  await DoMethodAsync();
}

2:

->

2:

public Task ProcessUploadedFile(FileInfo info, string contentType)
    {
      foreach (var something in someCollection)
        DoSomething();

      DoSomethingElse();

      return DoMethodAsync();
    }

我最初写了前者,但现在认为加上await没有意义。如果我写后者,可以实现相同的效果,并且两种方法的调用者仍然可以选择使用await关键字。

上述两种方法有什么区别?哪一个更好?

1个回答

18
"await用于在等待完成时继续执行方法体。如果没有需要继续执行的内容,那么就不需要使用await

你可以把await(简化)看作是ContinueWith操作。因此,你的第一个方法应该是这样的:

"
foreach (var something in someCollection)
     DoSomething();

DoSomethingElse();

DoMethodAsync().ContinueWith(t => {});

有一篇很不错的 MSDN 文章,描述了异步方法中发生的事件, 并附有清晰易懂的代码流程图:

enter image description here


1
等一下。我能澄清一些事情吗?在你重写我的代码的版本中,你把DoSomething()和DoSomethingElse()放在了Task.Factory.StartNew()里面……是这样吗?我原本认为这些部分会在调用者的同一个线程上同步运行,而且应该是DoMethodAsync().ContinueWith(t => {}_);? - dark_perfect
1
@dark_perfect 抱歉,当时有点赶。没错,你是完全正确的。已更新代码。 - Sergey Berezovskiy
3
即使您之后不需要执行任何操作,当您想要捕获异步方法的异常时,也应该使用 await。 - Adi Lester
2
@Adi 即使我返回Task(而不是等待它),我的方法的调用者仍然可以等待返回的Task以捕获异常,对吧?所以在这种情况下,这不会有任何区别,对吗? - dark_perfect
还有一件事要记住:如果你决定放弃"async",那么"return null;"将成为Task<XyClass>,也就是null!因此,你必须更改值返回到这样的习语:'return Task.FromResult((XyClass)null);'——这是一个已经设置了结果的快速任务。 - Robetto

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接