我是C#的新手,我觉得异常有点令人困惑...... 我有一个带有以下代码的Web应用程序:
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
?那是为什么?
答案 0 :(得分:6)
在捕获Exception
时,您必须确保完全抛出异常。使用Task.Run
或Task.Factory.Startnew
并且通常涉及从Task
抛出异常时(除非正在等待使用await
关键字的任务),外部异常就是处理是AggregateException
,因为Task
单位可能有子任务,也可能会抛出异常。
来自Exception Handling (Task Parallel Library):
正在运行的用户代码引发的未处理异常 任务内部传播回连接线程,除了 本主题后面介绍的某些方案。例外 当您使用静态或实例Task.Wait或其中一个时传播 Task.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);
}