为什么不在GC.Collect上重新抛出任务异常

时间:2012-10-14 15:40:42

标签: c# c#-4.0 task

我的理解是当一个Task抛出异常时,当观察到Tasks的(Result,WaitAll)属性或GC发生时,它会被存储并重新抛出。鉴于此,我运行以下代码。

Task t = Task.Factory.StartNew(() =>
{                    
    throw new Exception("Hello World");
});

for (int i = 0; i < 10000; i++)
{
    Console.WriteLine(i);
}    

 GC.Collect();

 for (int a = 20; a < 30; a++)
 {
      Console.WriteLine(a);
 }

但是当我运行上面的代码时,我除了在GC.Collect上抛出一个异常但它没有发生,而是继续从第二个循环打印输出。我的理解在哪里错了?

2 个答案:

答案 0 :(得分:5)

在您的示例代码中,Task对象t仍在范围内,因此在您致电GC.Collect()时不符合收集条件。

除此之外,.NET 4.0和.NET 4.5之间的行为发生了变化:

在.NET 4.0中,未观察到的异常会在终结器线程上引发异常,从而导致进程崩溃。

在.NET 4.5中,此行为已更改,因此默认情况下会忽略未观察到的异常。您可以设置一个配置开关来重新打开旧的严格行为。

.NET 4.0: Tasks and Unhandled Exceptions

.NET 4.5: Task Exception Handling in .NET 4.5

答案 1 :(得分:0)

因为使用Task就像使用单独执行的Thread(除了主线程)。因此,这样您就可以执行循环输出以及 GC.Collect ,直到任务执行异常行为止。