C# Tasks - 为什么在这种情况下需要 noop 行

C# Tasks - Why a noop line is needed in this case

我正在阅读 Interactive Extensions 的源代码,发现了一个我无法理解的 line

public static Task<bool> UsingEnumerator(this Task<bool> task, IDisposable disposable)
{
    task.ContinueWith(t =>
    {
        if (t.IsFaulted)
        {
            var ignored = t.Exception; // don't remove!
        }

        if (t.IsFaulted || t.IsCanceled || !t.Result)
            disposable.Dispose();
    }, TaskContinuationOptions.ExecuteSynchronously);

    return task;
}

我在文档中也没有看到任何关于 IsFaultedException 属性的相关评论。

为什么在此上下文中需要这一行 var ignored = t.Exception; // don't remove!

一个相关的问题:我认为这些行在发布模式下被优化掉了,但考虑到这里的评论和意图,情况并非如此(如果代码是正确的)。那为什么这条线一直停留在Release模式呢?

该行是 观察到的异常和未观察到的异常之间的区别。

在 .Net 4.0 中,具有未观察到异常的任务将抛出 UnobservedTaskException 并拆除整个应用程序:

"If you do not wait on a task that propagates an exception, or access its Exception property, the exception is escalated according to the .NET exception policy when the task is garbage-collected."

来自Exception Handling (Task Parallel Library)

虽然您可以使用 app.config (<ThrowUnobservedTaskExceptions enabled="true"/>).

,但在 .Net 4.5 中已通过 async-await 更改了旧行为

还有一个事件 (TaskScheduler.UnobservedTaskException) 允许您在应用程序崩溃之前处理此类错误任务。该事件仍在 .Net 4.5 及更高版本中引发。