Я пытался объяснить коллеге, почему функции async void
плохи и что исключения не будут пойманы, но, оказывается, я, возможно, не понимаю их правильно. У нас есть кусок кода, который выглядит немного как это:Функция MVC возвращает, но ждет асинхронной функции перед отправкой результата
public ActionResult EmailCandidates(List<string> identityTokens, string subject, string content)
{
// generate list of recipients here
SendEmail(recipients, subject, content); //not awaited
return new AjaxResponse { // AjaxResponse is a wrapper around JSONResponse
IsSuccess = true,
Data = recipients.Select(r=>r.Name)
};
}
private async void SendEmail(List<EmailAddress> recipients, string subject, string content)
{
await Task.Delay(10000); // simulate async send email
throw new Exception(); // manually added
}
То, что я ожидал, и то, что я пытался объяснить, что если функция SendEmail
бросает исключение не будет пойман должным образом, потому что основная функция EmailCandidates
уже вернулась к клиенту. Только это не так. Код выше выполняется в точном порядке, я ожидаю:
- вызова сделан от клиента
EmailCandidates
SendEmail
называется- письмо отправляется асинхронно (моделируется здесь через асинхронное ожидание)
- управление возвращается к
EmailCandidates
, и возвращение выполняется
, а затем он получает довольно странно:
- На данный момент, я ожидал получить ответ клиенту, но я не делаю, даже если
EmailCandidates
вернулся - 10 секунд спустя исключение
- исключение перехватывается глобальной ошибки обработчик, и теперь клиент получает ошибку 500 (неудивительно)
Так почему же хотя EmailCandidates
вернулся, ответ не отправляется клиенту. Как знать, ждать функции async SendEmail
?
быстрый вопрос, что у вас есть на этой конфигурации, которая находится внутри вашего webconfig? –
Zinov
@ Zinov веб-конфигурация довольно велика, но пользовательская ошибка ' ' –
Anduril
проверить ниже мой ответ – Zinov