Использование ConfigureAwait (false) для задач, переданных в Task.WhenAll() не выполняется

Я пытаюсь решить, как ждать завершения всех задач async.

Вот код, который у меня в настоящее время есть

[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 имеет недопустимые аргументы, потому что она не будет принимать настроенные задачи Awaiatables.

Итак, Task.WhenAll необходимо заменить на

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

Это не кажется мне правильным, но практически везде есть что сказать об ConfigureAwait, это "использовать его, если это не ошибка". И, насколько я знаю (я не писал задачи), они не используют синхронный контекст и не полагаются на него.

Важно отметить, что задача Task1 через task4 должна выполняться одновременно, так как они не полагаются на предыдущую. В результате я не хочу ждать перед каждой задачей. Но я не хочу возвращать ответ Json до тех пор, пока все 4 не закончатся, поэтому у меня в настоящее время есть Task.WhenAll() в текущем коде.

Ответ 1

Вам нужно только 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);
}