如何在未处理的任务异常上崩溃?
How to crash on unhandled Task exception?
我想正确理解未能观察到在 Task
中使用的 Task
抛出的异常而没有异常处理的后果。
这里是 Jeffry Richter 的 CLR via C# 摘录,第三版:“[...] 当一个 Task
对象被垃圾回收时,它的 Finalize
方法检查是否 Task
遇到未观察到的异常;如果有,Task
的 Finalize
方法抛出 [异常]。由于您无法捕获 CLR 的终结器线程抛出的异常,您的进程将立即终止."
我正在编写一些测试代码来实现终止,但无法实现。
使用测试代码 here,我可以看到正在调用 TaskScheduler.UnobservedTaskException
处理程序。但是,如果我注释掉事件处理程序订阅,则异常似乎被吞没并且不会导致程序终止。
我已经在版本 4 和 4.8 上使用 .NET Framework 进行了发布构建。
如何证明未能观察到 Task
上抛出的异常确实会导致崩溃?
Jon Skeet 在他的 中正确识别了问题 post。
我找到的有关此主题的最佳资源来自 Stephen Toub。
tldr:
“为了让开发人员更容易编写基于任务的异步代码,.NET 4.5 更改了未观察到的异常的默认异常行为。虽然未观察到的异常仍会导致引发 UnobservedTaskException 事件(不这样做将是一个重大变化),默认情况下,进程不会崩溃。相反,无论事件处理程序是否观察到异常,异常都会在引发事件后被吃掉。不过,可以配置此行为。可以使用新的 CLR 配置标志来恢复到 .NET 4 的崩溃行为,例如
<configuration>
<runtime>
<ThrowUnobservedTaskExceptions enabled=”true”/>
</runtime>
</configuration>
我想正确理解未能观察到在 Task
中使用的 Task
抛出的异常而没有异常处理的后果。
这里是 Jeffry Richter 的 CLR via C# 摘录,第三版:“[...] 当一个 Task
对象被垃圾回收时,它的 Finalize
方法检查是否 Task
遇到未观察到的异常;如果有,Task
的 Finalize
方法抛出 [异常]。由于您无法捕获 CLR 的终结器线程抛出的异常,您的进程将立即终止."
我正在编写一些测试代码来实现终止,但无法实现。
使用测试代码 here,我可以看到正在调用 TaskScheduler.UnobservedTaskException
处理程序。但是,如果我注释掉事件处理程序订阅,则异常似乎被吞没并且不会导致程序终止。
我已经在版本 4 和 4.8 上使用 .NET Framework 进行了发布构建。
如何证明未能观察到 Task
上抛出的异常确实会导致崩溃?
Jon Skeet 在他的
我找到的有关此主题的最佳资源来自 Stephen Toub。
tldr: “为了让开发人员更容易编写基于任务的异步代码,.NET 4.5 更改了未观察到的异常的默认异常行为。虽然未观察到的异常仍会导致引发 UnobservedTaskException 事件(不这样做将是一个重大变化),默认情况下,进程不会崩溃。相反,无论事件处理程序是否观察到异常,异常都会在引发事件后被吃掉。不过,可以配置此行为。可以使用新的 CLR 配置标志来恢复到 .NET 4 的崩溃行为,例如
<configuration>
<runtime>
<ThrowUnobservedTaskExceptions enabled=”true”/>
</runtime>
</configuration>