Tpl的延续和例外?

时间:2013-02-23 16:49:45

标签: c# .net-4.0 task-parallel-library task

如果我有一个抛出异常的任务,我可以检查继续是否有异常:

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

但我也知道:

  

如果先行抛出并且继续失败来查询   先前的异常财产(前提是其他情况   等待),该例外被认为是未处理的   申请死亡

所以我试过了:

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

但是应用程序没有崩溃。

拜托,我错过了什么?

1 个答案:

答案 0 :(得分:5)

正在发生的事情很少:

首先,如果您在出错的Wait()上致电Task,则总是会抛出异常,无论您是否已经观察过它。在您的代码中,这意味着如果您从task.Wait()致电Main(),整个应用程序都会崩溃,因为您在Main()中有未处理的异常。

其次,the behavior of unhandled exceptions in Tasks changed in .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在应用程序正常退出之前没有机会运行。