【问题标题】:Awaiting tasks: Return task or await if no code after await [duplicate]等待任务:如果等待后没有代码,则返回任务或等待[重复]
【发布时间】:2013-08-06 09:03:58
【问题描述】:

我已经阅读了一些内容,并且认为我已经掌握了关于 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:

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

      DoSomethingElse();

      return DoMethodAsync();
    }

我最初写的是前者,但不再看到添加等待的意义。如果我写后者,我完成了同样的事情,并且两个方法的调用者如果选择仍然可以使用 await 关键字,不是吗?

上面有什么不同吗?哪个“更好”?

【问题讨论】:

    标签: .net task-parallel-library async-await


    【解决方案1】:

    await 用于在等待完成时继续执行方法体。如果没有什么可以继续的,那么你就不需要等待了。

    您可以将 await(简化)视为 ContinueWith 操作。所以,你的第一个方法是这样的:

    foreach (var something in someCollection)
         DoSomething();
    
    DoSomethingElse();
    
    DoMethodAsync().ContinueWith(t => {});
    

    有一篇很好的 MSDN 文章描述了what happens in async method,其中有很好的代码流程图:

    【讨论】:

    • 等等。我可以澄清一下吗?在您重写的我的代码版本中,您在 Task.Factory.StartNew() 中有 DoSomething() 和 DoSomethingElse() ......对吗?我认为这些位会在与调用者相同的线程上同步运行?这将是 DoMethodAsync().ContinueWith(t => {}_); ?
    • @dark_perfect 抱歉,很着急。是的,你是完全正确的。更新代码
    • 当你想从异步方法中捕获异常时,你也应该等待,即使你之后不需要做任何事情。
    • @Adi 即使我返回任务(而不是等待),我的方法的调用者仍然可以等待返回的任务以捕获异常,对吧?所以在这种情况下,它不会有任何区别,不是吗?
    • 还有一件事要记住:如果您决定放弃“异步”,则“返回 null;”然后将是 Task - 所以为空! .因此,您不必将代码 1:1 保留,而是必须将值返回更改为这样的习语:'return Task.FromResult((XyClass)null);' - 这是一个快速的任务,结果已经确定。
    猜你喜欢
    • 2017-06-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-01
    • 2016-10-27
    • 2016-09-10
    • 2014-09-06
    相关资源
    最近更新 更多