ContinueWith 没有捕获异常?

Roy*_*mir 5 c# continuewith

使用 Visual Studio 2015,针对 FW 4(在 FW 4 下测试不可观察的异常):

在此输入图像描述

我期待这段代码:

static void Main(string[] args)
{

    try
    {
        Task.Factory.StartNew(() => Console.WriteLine(1))
        .ContinueWith(t => Thread.Sleep(1000))
        .ContinueWith(t => Console.WriteLine(2))
        .ContinueWith(t => Thread.Sleep(1000))
        .ContinueWith(t => { throw new Exception("aaaa"); })
        .ContinueWith(t => Console.WriteLine(3));
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex);

    }
    GC.Collect();
    GC.Collect();
    Console.ReadLine();
}
Run Code Online (Sandbox Code Playgroud)

向我展示例外情况。

我知道我可以通过T.Wait()或在最后一个任务中看到它t.Exception- 但为什么我在这里没有看到异常?

我知道异常处理机制在 4.5 中发生了变化,为了获得旧的机制,我应该添加:

 <ThrowUnobservedTaskExceptions enabled="true"/>
Run Code Online (Sandbox Code Playgroud)

我做了什么:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <startup> 
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>
    </startup>
  <runtime>
    <ThrowUnobservedTaskExceptions enabled="true"/>
  </runtime>
</configuration>
Run Code Online (Sandbox Code Playgroud)

但结果仍然是:

在此输入图像描述

问题:

为什么我没有看到异常?

值得一提的是,我确实在调试模式下看到了异常:

在此输入图像描述

Dar*_*rov 4

您不能期望此代码抛出异常,因为子句中的语句所做的只是try描述延续模式。和方法不会引发异常StartNew。所以当后台任务抛出异常时,ContinueWith代码执行早就离开了这条语句。try当程序启动后大约 2 秒后抛出异常时,语句的执行将停止Console.Readline

正如您已经发现的,您需要等待任务完成才能访问异常或延续本身。

现在,您的应用程序不会因未观察到的异常而终止的原因是因为垃圾收集尚未发生。当任务被垃圾收集时,未观察到的异常将破坏您的应用程序域。但是,当您强制 GC 时,尚未引发异常,任务也尚未完成,因此不符合垃圾收集的条件。

确保您该方法之后调用另一个GC.Collect方法:Console.ReadLineConsole.ReadLine

Task.Factory.StartNew(() => Console.WriteLine(1))
    .ContinueWith(t => Thread.Sleep(1000))
    .ContinueWith(t => Console.WriteLine(2))
    .ContinueWith(t => Thread.Sleep(1000))
    .ContinueWith(t => { throw new Exception("aaaa"); })
    .ContinueWith(t => Console.WriteLine(3));

Console.ReadLine();
GC.Collect();
GC.Collect();
Console.ReadLine();
Run Code Online (Sandbox Code Playgroud)

显然应该存在以下配置开关:

<ThrowUnobservedTaskExceptions enabled="true"/>
Run Code Online (Sandbox Code Playgroud)