C# · 12月 27, 2021

C#任务 – 为什么在这种情况下需要noop行

我正在阅读互动扩展程序的源代码,并发现了一个我不明白的 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;}

我也没有在文档中看到有关IsFaulted或Exception属性的任何相关的备注.

为什么这行var ignored = t.Exception; //不要删除!在这种情况下是需要的吗?

一个相关的问题:我认为这样的行在发布模式下被优化了,但是在这里给出了评论和意图,情况并非如此(如果代码是正确的).那么为什么这条线保持在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及以上仍在提高.