我的理解是当一个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上抛出一个异常但它没有发生,而是继续从第二个循环打印输出。我的理解在哪里错了?
答案 0 :(得分:5)
在您的示例代码中,Task
对象t
仍在范围内,因此在您致电GC.Collect()
时不符合收集条件。
除此之外,.NET 4.0和.NET 4.5之间的行为发生了变化:
在.NET 4.0中,未观察到的异常会在终结器线程上引发异常,从而导致进程崩溃。
在.NET 4.5中,此行为已更改,因此默认情况下会忽略未观察到的异常。您可以设置一个配置开关来重新打开旧的严格行为。
答案 1 :(得分:0)
因为使用Task就像使用单独执行的Thread(除了主线程)。因此,这样您就可以执行循环输出以及 GC.Collect ,直到任务执行异常行为止。