繁体   English   中英

Tpl的延续和例外?

[英]Tpl's Continuations and exceptions?

如果我有一个引发异常的任务,则可以在延续中检查是否存在异常:

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

但是应用程序没有崩溃。

拜托,我想念什么?

发生了几件不同的事情:

首先,如果对有故障的Task调用Wait() ,它将始终引发异常,无论您是否已经观察到它。 在您的代码中,这意味着如果您从Main()调用task.Wait() ,则整个应用程序将崩溃,因为Main()有未处理的异常。

其次, .NET 4.5中Task中未处理的异常的行为已更改 ,它们将不再导致应用程序崩溃。 本文还介绍了如何切换回原始行为。 如果您安装了.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没有机会运行。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM