6

我的理解是,当 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 抛出一个异常,但它没有发生,而是继续打印第二个循环的输出。我的理解哪里错了?

4

2 回答 2

5

在您的示例代码中,该Task对象t仍在范围内,因此在您调用GC.Collect().

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

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

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

.NET 4.0:任务和未处理的异常

.NET 4.5:.NET 4.5 中的任务异常处理

于 2012-10-14T16:03:00.213 回答
0

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

于 2012-10-14T15:51:43.037 回答