#c# #async-await
#c# #async-await
Вопрос:
BackgroundService
Класс содержит следующий код:
public virtual Task StartAsync(CancellationToken cancellationToken)
{
// Store the task we're executing
_executingTask = ExecuteAsync(_stoppingCts.Token);
// If the task is completed then return it, this will bubble cancellation and failure to the caller
if (_executingTask.IsCompleted)
{
return _executingTask;
}
// Otherwise it's running
return Task.CompletedTask;
}
Я прочитал https://www.markopapic.com/csharp-under-the-hood-async-await / что заставляет меня предположить, что весь код ExecuteAsync
вплоть до его первого (если таковой имеется) await ...
выполняется до if (_executingTask.IsCompleted)
достижения. Поэтому, если в этой части ExecuteAsync
возникает какое-либо исключение или если ExecuteAsync
возвращается Task.CompletedTask
, это приведет к выполнению return _executingTask;
.
Правильно ли я это понимаю?
Комментарии:
1. Примечание: я не удивлюсь, если это дубликат более общего вопроса async / await, но большое количество вопросов async / await по SO не позволяет легко найти информацию, которую я ищу.
Ответ №1:
Итак, если в этой части ExecuteAsync возникает какое-либо исключение или ExecuteAsync возвращает задачу.Завершенная задача, которая приведет к выполнению return _executingTask;
В более общем плане, если ExecuteAsync
выполняется синхронно, то StartAsync
возвращается задача, возвращенная из ExecuteAsync
.
В данном конкретном случае (с фоновыми службами) я полагаю, что он предназначен для обработки таких вещей, как проверки предварительных условий, которые обычно выполняются синхронно в начале асинхронного метода. Итак, если фоновая служба синхронно определяет, что она не может быть запущена, то StartAsync
вернет задачу с ошибкой.
Такой код встречается крайне редко, а дизайн сомнителен. Например, если фоновая служба асинхронно определяет, что она не может быть запущена, то уведомления об этом нет. Я думаю, что поведение было бы более последовательным для удаления всего if (_executingTask.IsCompleted)
блока или изменения ExecuteAsync
абстракции на отдельные InitializeAsync
и ExecuteAsync
части.