Заняты ли потоки при использовании async/await?

Есть ли разница между
Task.Run(() => {
 ... long wait IO bound operation
});

и
await LongIOBoundOperaion();

В первом случае поток будет занят ожиданием завершения IO операции, а во втором, будет ли какой-то поток ждать выполнения или поток будет создан(взят свободный из пула) после уведомления о том, что IO операция завершена?
  • Вопрос задан
  • 1930 просмотров
Решения вопроса 1
AlekseyNemiro
@AlekseyNemiro
full-stack developer
https://msdn.microsoft.com/ru-ru/library/hh156528.aspx
Выражение await не блокирует поток, в котором оно выполняется. Вместо этого оно указывает компилятору объявить оставшуюся часть асинхронного метода как продолжение ожидаемой задачи. Управление затем возвращается методу, вызвавшему асинхронный метод. Когда задача завершается, она вызывает свое продолжение и возобновляет выполнение асинхронного метода с того места, где она была прервана.

Метод Task.Run ставит в очередь заданную задачу для запуска в пуле потоков.

Т.е. в первом случае, у вас просто будет добавлена задача в очередь на выполнение и продолжено выполнение программы (без ожидания, программа может завершить работу раньше, чем созданная задача). А во втором, текущий поток будет ожидать завершения выполнения асинхронной операции. Основной поток при использовании await заморожен не будет.

// без ожидания
Console.WriteLine(DateTime.Now);

Task.Run(() => { Thread.Sleep(5000); });

// этот код будет выполнен сразу
Console.WriteLine(DateTime.Now);

// ожидание с await
Console.WriteLine(DateTime.Now);

await Task.Run(() => { Thread.Sleep(5000); });

// этот код будет выполнен, только после завершения выполнения задачи
// текущий (вызывающий) поток не будет приостановлен
// (например, в Windows Form это будет хорошо видно)
Console.WriteLine(DateTime.Now);

Если сделать задачу и вызвать метод Wait, то основной поток будет приостановлен, пока не завершится задача.

Console.WriteLine(DateTime.Now);

var t = Task.Run(() => { Thread.Sleep(5000); });
t.Wait(); // ожидание выполнения задачи

// этот код будет выполнен, только после завершения выполнения задачи
// текущий (вызывающий) поток будет блокирован
// (например, в Windows Form это будет хорошо видно)
Console.WriteLine(DateTime.Now);

74ad1b048cee439faab48113a61a7ec7.gif
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы