Как ни странно, ключевое слово async
не превратит ваши методы в магические асинхронные.Вместо этого вы можете рассматривать async
методы как установку для конечного автомата (см. Подробное объяснение здесь ), где вы планируете цепочку операций с помощью вызовов await
.
По этой причине ваши асинхронные методы должны выполняться максимально быстро.Не выполняйте никаких операций блокировки в таком методе настройки.Ваш метод GetIntAfterLongWait
является блокирующей операцией, и, поскольку он не содержит никаких await
s, весь контент будет выполняться немедленно при вызове метода (без каких-либо await
в методе нет ничего для установки асинхронного продолжения).).Об этом также должно быть предупреждение.
Если у вас есть операция блокировки, которую вы хотите выполнить в асинхронном методе, возможный вариант - запланировать ее с помощью вызова await Task.Run(() => MyLongOperation());
.
Так, например, следующий пример вернется немедленно, потому что нечего выполнять перед первым await
.Оператор возврата будет выполняться асинхронно как продолжение после завершения внутренней ожидаемой задачи:
public async Task<int> GetIntAfterLongWait()
{
await Task.Run(() =>
{
for (int i = 0; i < 500000000; i++)
{
if (i % 10000000 == 0)
{
Console.WriteLine(i);
}
}
});
return 23;
}
Подробнее см. По ссылке выше.
Обновление:
Эта версия будет печатать:
1)
2)
<long list of ints> - but 0 can be before even 1) as Task.Run uses another thread
3)
4)