TimeoutException, TaskCanceledException C#

Я новичок в C# и я нахожу исключений немного запутанным... У меня есть веб-приложение со следующим кодом:

try
{
    //do something
}
catch (TimeoutException t)
{
    Console.WriteLine(t);
}
catch (TaskCanceledException tc)
{
    Console.WriteLine(tc);
}
catch (Exception e)
{
    Console.WriteLine(e);
}

когда я отлаживаю код, он бросает e Exception, самый общий, и когда я наведу курсор на информацию об исключении, оказывается, что это TaskCanceledException. Почему это TaskCanceledException поймал? Если исключение было TimeoutException поймает ли он TimeoutException или он также поймает Exception? Почему так?

1 ответов


при ловле Exception, вы должны убедиться, что это ровно создается исключение. При использовании Task.Run или Task.Factory.Startnew и вообще с участием исключения, выбрасываемого из Task (если только задача не будет ожидаться с await ключевое слово), внешним исключением, с которым вы имеете дело, является AggregateException, потому что Task единица может иметь дочерние задачи, которые могут создавать исключения.

С исключение Обработка (Параллельная Библиотека Задач):

необработанные исключения, создаваемые запущенным кодом пользователя внутри задачи распространяются обратно к соединяющему потоку, за исключением некоторые сценарии, описанные ниже в этом разделе. Исключения распространяются при использовании одной из задач static или instance.Ждать или Задача.Методы Wait, и вы обрабатываете их, заключая вызов в try-catch блока. Если задача родителя добавленные ребенка задачи, или если вы ждете нескольких задач, то несколько возможны исключения. Чтобы распространить все исключения обратно на вызывающий поток, инфраструктура задач обертывает их в AggregateException экземпляр. Исключение AggregateException имеет Свойство InnerExceptions, которое можно перечислить для проверки всех оригинальный исключения, которые были брошены, и обрабатывать (или не обрабатывать) каждый один индивидуально. Даже если выбрасывается только одно исключение, оно все еще завернутый в AggregateException.

Итак, чтобы справиться с этим, вы должны поймать AggregateException:

try
{
    //do something
}
catch (TimeoutException t)
{
    Console.WriteLine(t);
}
catch (TaskCanceledException tc)
{
    Console.WriteLine(tc);
}
catch (AggregateException ae)
{
   // This may contain multiple exceptions, which you can iterate with a foreach
   foreach (var exception in ae.InnerExceptions)
   {
       Console.WriteLine(exception.Message);
   }
}
catch (Exception e)
{
    Console.WriteLine(e);
}