TimeoutException,TaskCanceledException C#

时间:2014-07-21 13:35:37

标签: c# exception-handling timeoutexception

我是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?那是为什么?

1 个答案:

答案 0 :(得分:6)

在捕获Exception时,您必须确保完全抛出异常。使用Task.RunTask.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);
}