После замены двоеточий на точки с запятой будут M1: NotImplementedException и M2: AggregateException. M0 не выводится: ошибка async Task хранится в возвращённой задаче.
Исключения в асинхронных вызовах: где они отлавливаются?
После замены двоеточий на точки с запятой будут M1: NotImplementedException и M2: AggregateException. M0 не выводится: ошибка async Task хранится в возвращённой задаче.
Короткий ответ
Что ответить на собеседовании
Подробный разбор
Ответ с пояснениями
Условие
Определите, в какие блоки catch будет перехвачено выброшенное исключение и какие строки появятся в выводе консоли.
using static System.Console;
async Task RunAsync() => throw new NotImplementedException();
Task myTask = Task.CompletedTask;
try
{
myTask = RunAsync();
}
catch (Exception caught)
{
Console.WriteLine($"M0: {caught.GetType().Name}"):
}
try
{
await myTask;
}
catch (Exception caught)
{
Console.WriteLine($"M1: {caught.GetType().Name}"):
}
try
{
myTask.Wait();
}
catch (Exception caught)
{
Console.WriteLine($"M2: {caught.GetType().Name}"):
}
Ответ
После замены двоеточий на точки с запятой будут M1: NotImplementedException и M2: AggregateException. M0 не выводится: ошибка async Task хранится в возвращённой задаче.
Вызов RunAsync возвращает уже faulted Task, хотя внутри нет await. Поэтому присваивание myTask само не выбрасывает NotImplementedException. Ожидание через await извлекает исходное исключение, а Wait сообщает о сбое через AggregateException.
M1: NotImplementedException
M2: AggregateException
Исходные строки Console.WriteLine заканчиваются :, поэтому буквально данный код не компилируется. Отсутствие await внутри async-метода — предупреждение, но не причина синхронного проброса. У обычного метода без async, который бросает до возврата Task, поведение было бы другим.