对传递给Task.WhenAll()的任务使用ConfigureAwait(false)失败

时间:2015-06-05 15:57:00

标签: c# asynchronous async-await

我正在尝试决定如何等待所有异步任务完成。

这是我目前的代码

[HttpGet]
public async Task<JsonResult> doAsyncStuff()
{
  var t1 = this.service1.task1();
  var t2 = this.service2.task2();
  var t3 = this.service3.task3();
  var t4 = this.service4.task4();

  await Task.WhenAll(t1,t2,t3,t4);
  return this.Json(new {redirect = true, href = Url.Action("Blah")}, JsonRequestBehavior.AllowGet);
}

我很确定同步上下文不相关所以我试过了。

[HttpGet]
public async Task<JsonResult> doAsyncStuff()
{
  var t1 = this.service1.task1().ConfigureAwait(false);
  var t2 = this.service2.task2().ConfigureAwait(false);
  var t3 = this.service3.task3().ConfigureAwait(false);
  var t4 = this.service4.task4().ConfigureAwait(false);

  await Task.WhenAll(t1,t2,t3,t4);
  return this.Json(new {redirect = true, href = Url.Action("Blah")}, JsonRequestBehavior.AllowGet);
}

问题是现在Task.WhenAll的参数无效,因为它不接受Configured Task Awaiatables。

所以Task.WhenAll需要替换为

await t1; await t2; await t3; await t4;

这对我来说似乎不正确,但几乎所有人都对ConfigureAwait有任何说法,如果它没有错误就“使用它”。据我所知(我没有编写任务),他们不使用同步上下文,也不依赖它。

重要的是要注意我希望task1到task4同时运行,因为它们不依赖于前一个完成。因此,我不想在每项任务面前等待。但是我不想在完成所有4个完成之后返回Json响应,这就是为什么我当前在当前代码中有等待Task.WhenAll()的原因。

1 个答案:

答案 0 :(得分:46)

实际执行ConfigureAwait时,您只需要await,正确的格式将是

[HttpGet]
public async Task<JsonResult> doAsyncStuff()
{
  var t1 = this.service1.task1();
  var t2 = this.service2.task2();
  var t3 = this.service3.task3();
  var t4 = this.service4.task4();

  await Task.WhenAll(t1,t2,t3,t4).ConfigureAwait(false);
  return this.Json(new {redirect = true, href = Url.Action("Blah")}, JsonRequestBehavior.AllowGet);
}