Они очень похожи на , но есть шанс, что DoStuff
может завершиться синхронно; если это произойдет, ваш второй (только await
) метод будет блокироваться на сколько угодно времени, в то время как первый (Task.Run
) всегда будет возвращать неполный вызывающему (раскручивание их стека и планирование продолжения) и блокирующая работа выполняется в потоке пула.
Оба варианта могут быть желательными в разных сценариях ios!
Однако есть третий вариант, который выражает точно намерение «запустить остальное в другом месте» до тех пор, пока у вас нет SyncContext
:
public async Task LongRunningMethod()
{
await Task.Yield();
await DoStuff(); // possibly with .ConfigureAwait(false)
}
Если нет SyncContext
, это функционально аналогично версии Task.Run
(что означает: она всегда будет возвращаться вызывающей стороне как неполная и запускать DoStuff
, начиная с пула), только: без фактических Task.Run
бит. Однако, если есть , это a SyncContext
: go вернется в тот же контекст, что ... неудобно, и, к сожалению, ConfigureAwait(false)
для YieldAwaitable
, поэтому в этом случае вам нужно будет использовать Task.Run
или аналогичный.