【问题标题】:C# - Await and asyncC# - 等待和异步
【发布时间】:2017-04-17 07:33:10
【问题描述】:

只是想确保我能正确理解这一点,因为我看到了一些基于我的结果的奇怪行为。

我已经定义了一个异步方法如下:

public async Task<System.Net.HttpStatusCode> GetJson(Stream inputJson)
{
  ......
  .....
  ...
  var query1 = from xxx in new xxx()
               where xxx.id == myID
               select xxx;
  var results1 = await query1.FindAsync();

  var query2 = from yyy in new yyy()
               where yyy.id == myID
               select yyy;
  var results2 = await query2.FindAsync();
  ...
  ....
  .....
  return System.Net.HttpStatusCode.OK;
}

query2 将仅在 query1 执行完毕后执行吗?还是并行?

【问题讨论】:

  • query2 将在query1 产生结果后执行。
  • @Polis:一个好的思维捷径是:await 表示“异步等待”,所以它确实等待。它只是异步等待而不是阻塞。

标签: c# wcf asynchronous parse-platform


【解决方案1】:

await 之后的代码被构造为所谓的延续。关键部分是这一行:

var results1 = await query1.FindAsync();

FindAsync 构造一个Task 然后await 表示其余的应该是该任务的继续。

这意味着该方法的其余部分将是另一个Task,并且该任务只会在第一个完成后执行。更重要的是,如果第一个任务抛出异常,第二个甚至都不会启动。

因此,您的问题的答案是:是的,query2 将始终在 query1 完成后执行。

【讨论】:

  • 谢谢。出于好奇,如果异步方法中的大部分代码都标有等待,那么它不是优于异步方面吗?我的意思是你不妨同步运行所有东西,对吧?顺便说一句,我是在暗示一个与 UI 无关的过程。
  • 尝试从 CPU 的角度来看。不完全受 CPU 限制的操作,如数据库或网络操作,将返回对它们正在执行的线程的控制。这将让任务管理器在同一线程上运行其他任务,从而提高整体 CPU 利用率。同步执行所有这些操作会降低 CPU 利用率,因为当前线程将被阻塞,并且必须为其他任务启动另一个线程。
【解决方案2】:

在您的情况下,query1 将启动,并且该方法将暂停执行,直到 query1 完成。只有这样query2 才会启动。如果您想并行执行它们,请查看 Task.WhenAll(...) MSDN

【讨论】:

    【解决方案3】:

    是的,query2 将在await query1.FindAsync() 返回结果后执行。但要注意它将继续哪个线程。这取决于。

    如果你想同时做,你可以使用Task.WhenAll 方法。 示例:

    var firstTask = FirstMethodAsync();
    var secondTask = SecondMethodAsync();
    await Task.WhenAll(firstTask, secondTask); 
    // Here you can pull out Results from firstTask and secondTask.
    var firstResult = firstTask.Result;
    var secondResult = secondTask.Result;
    

    有关 WhenAll 方法的更多信息,您可以在 MSDN 上找到 here

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-11-29
      • 2020-12-05
      相关资源
      最近更新 更多