Вызывается Task.Wait() сразу после асинхронной операции, эквивалентной одновременному выполнению одной и той же операции?

Другими словами,

var task = SomeLongRunningOperationAsync();
task.Wait();

функционально идентичен

SomeLongRunningOperation();

Иными словами,

var task = SomeOtherLongRunningOperationAsync();
var result = task.Result;

функционально идентичен

var result = SomeOtherLongRunningOperation();

В соответствии с Task.Wait и Inlining, если Task Wait d on уже начал выполнение, Wait должен блокироваться. Однако, если он еще не начал выполняться, Wait может вытащить целевую задачу из планировщика, к которому он был поставлен в очередь, и выполнить его inline в текущем потоке.

Являются ли эти два случая просто вопросом о том, какой поток будет запущен Task, и если вы все равно ожидаете результата?

Есть ли какая-либо польза от использования асинхронной формы в синхронной форме, если между асинхронным вызовом и Wait()?

Ответ 1

Вот некоторые отличия:

  • Вычисление может выполняться в другом потоке. Он может работать в одном потоке, если эта задача основана на процессорах и может быть встроена. Это не детерминировано.
  • Если никакой инкрустации не произойдет, во время вычисления будет использоваться еще один поток. Обычно это стоит 1 МБ памяти стека.
  • Исключения будут завернуты в AggregateException. Стек исключений будет другим.
  • Версия задачи может зайти в тупик, если вычисления отправляются в текущий контекст синхронизации.
  • Если пул потоков максимален, это может привести к блокировке, если задача для выполнения другой задачи должна быть запланирована.
  • Потоковое локальное состояние, такое как HttpContext.Current (которое фактически не является потоком, но почти), может отличаться.
  • Отключение потока основного потока не достигнет тела задачи (кроме случаев вложения). Я не уверен, будет ли само по себе ожидание или нет.
  • Создание Task вызывает барьер памяти, который может иметь эффект синхронизации.

Есть ли это? Решите сами по этому списку.

Есть ли преимущества для этого? Я не могу думать ни о чем. Если в вашем вычислении используется async IO, ожидание отрицает преимущества, которые приносит асинхронный ввод-вывод. Единственным исключением будет разветвление IO, например. выдавая 10 HTTP-запросов параллельно и ожидая их. Таким образом, у вас есть 10 операций за счет одного потока.

Обратите внимание, что Wait и Result эквивалентны во всех этих отношениях.