Как реализованы асинхронные процессы в приложении
Что проверяют
Здесь хотят услышать не определение async и await, а как асинхронность устроена в вашем приложении: где ввод-вывод, где фоновые задачи, как это отменяется и что происходит с ошибками. Следом обычно спрашивают, чем Task.Run отличается от await на сетевом вызове.
Как отвечать
Разделите ответ на два уровня.
Асинхронность внутри запроса. Async-метод компилятор превращает в машину состояний; пока идёт ввод-вывод (запрос в базу через EF Core, HttpClient, чтение файла), поток возвращается в пул и обслуживает другие запросы. Это масштабируемость, а не ускорение одного запроса. Независимые вызовы запускают вместе и ждут через Task.WhenAll, а CancellationToken протаскивают до самого низа, в ASP.NET Core его источник HttpContext.RequestAborted.
Фоновые процессы. Тут назовите то, что было у вас:
BackgroundService: долгоживущая задача в том же процессе, например разбор очереди. Scoped-зависимости берутся черезIServiceScopeFactory;Channel<T>: очередь производитель-потребитель в памяти с ограниченной ёмкостью, чтобы работа не копилась без предела;- Hangfire или Quartz.NET: задачи по расписанию и отложенные задачи с сохранением в базе и повторами;
- брокер: RabbitMQ или Kafka, часто через MassTransit, когда работа должна пережить рестарт и распределиться по экземплярам.
Task.Run нужен для CPU-нагрузки, чтобы не блокировать UI-поток в десктопе. В ASP.NET Core оборачивать им синхронный код бессмысленно: вы просто занимаете другой поток из того же пула. Для ограниченного параллелизма по коллекции есть Parallel.ForEachAsync с MaxDegreeOfParallelism.
Где спотыкаются
Блокируют асинхронный код через .Result или .Wait(). В UI и старом ASP.NET это взаимоблокировка, в ASP.NET Core голодание пула потоков под нагрузкой.
Защищают общее состояние через lock, а внутри нужен await. Компилятор это запрещает, для асинхронной синхронизации есть SemaphoreSlim.WaitAsync().
Пишут async void вне обработчиков событий или запускают задачу без await и без логирования. Исключение теряется или роняет процесс, а работа молча не выполняется.