1

如果我有一个引发异常的任务,如果有异常,我可以检查继续:

Task task1 = Task.Factory.StartNew (() => { throw null; });
Task task2 = task1.ContinueWith (ant => Console.Write (ant.Exception));

但我也知道:

如果前件抛出并且延续未能查询前件的 Exception 属性(并且没有以其他方式等待前件),则该异常被视为未处理并且 应用程序死亡

所以我尝试了:

Task task1 = Task.Factory.StartNew (() => { throw null; });
Task task2 = task1.ContinueWith (ant => Console.Write (1));//1

但应用程序没有崩溃。

请问,我错过了什么?

4

1 回答 1

5

发生了一些不同的事情:

首先,如果你调用Wait()一个 faulted Task,它总是会抛出一个异常,无论你是否已经观察到它。在您的代码中,这意味着如果您task.Wait()从调用Main(),整个应用程序将崩溃,因为您在Main().

其次, s中未处理异常的行为Task在 .Net 4.5 中发生了变化,它们将不再导致应用程序崩溃。本文还介绍了如何切换回原始行为。如果您安装了 .Net 4.5,这也适用于面向 .Net 4.0 的应用程序(例如使用 VS 2010 构建的应用程序)。

第三,对于 .net 4.0 行为,应用程序Task被垃圾回收时崩溃(假设在那之前没有观察到异常)。这是因为在此之前,您的代码仍有可能观察到该异常。

因此,以下代码使应用程序崩溃(假设您在安装了 .Net 4.5 的情况下启用了 .Net 4.0 行为):

static void Main()
{
    Task.Factory.StartNew(() => { throw new Exception(); });

    // give the Task some time to run
    Thread.Sleep(100);

    GC.Collect();
}

您的代码没有崩溃,因为在应用程序正常退出之前 GC 没有机会运行。

于 2013-02-23T17:30:23.573 回答