如果我有一个抛出异常的任务,我可以检查继续是否有异常:
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
但是应用程序没有崩溃。
拜托,我错过了什么?
答案 0 :(得分:5)
正在发生的事情很少:
首先,如果您在出错的Wait()
上致电Task
,则总是会抛出异常,无论您是否已经观察过它。在您的代码中,这意味着如果您从task.Wait()
致电Main()
,整个应用程序都会崩溃,因为您在Main()
中有未处理的异常。
其次,the behavior of unhandled exceptions in Task
s 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在应用程序正常退出之前没有机会运行。