В чем разница между синхронным и асинхронным выполнением async метода
Что проверяют
Понимаете ли вы, что async сам по себе ничего не ускоряет и потока не создаёт. Вопрос сформулирован хитро: он про то, что происходит внутри одного метода.
Как отвечать
Метод с async начинает выполняться синхронно, в вызывающем потоке, и продолжает так до первого await над незавершённой задачей. Если все ожидаемые задачи к этому моменту уже завершены (данные в кеше, значение готово), метод вообще не уходит в асинхронный путь и возвращает результат синхронно.
Когда встречается незавершённая задача, метод возвращает управление вызывающему, а остаток кода регистрируется как продолжение. Поток при этом освобождается и возвращается в пул. Именно в этом смысл асинхронности на вводе-выводе: сетевой запрос ждёт не поток, а операционная система.
Что важно проговорить:
asyncне создаёт поток. Вычислительную работу уводят в пул явно черезTask.Run, и это отдельное решение;awaitне блокирует, а.Resultи.Wait()блокируют, и в контексте с синхронизацией (старые ASP.NET, интерфейс WinForms и WPF) это классический источник взаимной блокировки;- продолжение возвращается в исходный контекст по умолчанию. В библиотечном коде это лишняя работа, поэтому там пишут
ConfigureAwait(false); в ASP.NET Core контекста синхронизации нет, и вопрос отпадает; async voidдопустим только для обработчиков событий: исключение из него нельзя поймать, оно роняет процесс.
Где спотыкаются
Оборачивают асинхронный вызов в Task.Run и занимают поток зря.
Считают, что метод с async целиком выполняется в другом потоке.
Делают async метод без единого await и получают предупреждение компилятора вместе с синхронным выполнением.