简体   繁体   English

如何在未处理的任务异常上崩溃?

[英]How to crash on unhandled Task exception?

I'd like to properly understand the consequences of failing to observe an exception thrown on a Task used in a fire and forget manner without exception handling.我想正确理解未能观察到在火灾中使用的Task上引发的异常的后果,并且在没有异常处理的情况下忘记了方式。

Here's an extract from CLR via C#, Third Edition by Jeffry Richter: "[...] when a Task object is garbage collected, its Finalize method checks to see if the Task experienced an unobserved exception; if it has, Task 's Finalize method throws [an exception]. Since you cannot catch an exception thrown by the CLR's finalizer thread, your process is terminated immediately."这是 Jeffry Richter 通过 C# 第三版从 CLR 中摘录的内容:“[...] 当一个Task object 被垃圾收集时,它的Finalize方法检查Task是否经历了未观察到的异常;如果有, TaskFinalize方法抛出[异常]。由于您无法捕获 CLR 的终结器线程抛出的异常,因此您的进程将立即终止。

I am writing some test code to bring about a termination but am unable to cause one.我正在编写一些测试代码来导致终止,但无法导致终止。

Using the test code here , I am able to see the TaskScheduler.UnobservedTaskException handler being called.使用此处的测试代码,我可以看到TaskScheduler.UnobservedTaskException处理程序被调用。 However, if I comment out the event handler subscription, the exception appears to be swallowed and does not bring about termination of the program.但是,如果我注释掉事件处理程序订阅,异常似乎被吞没了,不会导致程序终止。

I've tried this using the .NET Framework on both versions 4 and 4.8 with a Release build.我已经在版本 4 和 4.8 上使用 .NET 框架和发布版本进行了尝试。

How do I demonstrate that failing to observe an exception thrown on a Task does indeed cause a crash?我如何证明未能观察到Task引发的异常确实会导致崩溃?

The best resource I found concerning this topic is by Stephen Toub .我找到的关于这个主题的最佳资源是Stephen Toub的。

tldr: "To make it easier for developers to write asynchronous code based on Tasks, .NET 4.5 changes the default exception behavior for unobserved exceptions. While unobserved exceptions will still cause the UnobservedTaskException event to be raised (not doing so would be a breaking change), the process will not crash by default. Rather, the exception will end up getting eaten after the event is raised, regardless of whether an event handler observes the exception. This behavior can be configured, though. A new CLR configuration flag may be used to revert back to the crashing behavior of .NET 4, eg" tldr:“为了让开发人员更轻松地编写基于任务的异步代码,.NET 4.5 更改了未观察到的异常的默认异常行为。虽然未观察到的异常仍会导致引发 UnobservedTaskException 事件(不这样做将是一个重大更改) , 默认情况下进程不会崩溃。相反,无论事件处理程序是否观察到异常,异常最终都会在事件引发后被吃掉。不过,可以配置此行为。可以使用新的 CLR 配置标志恢复到 .NET 4 的崩溃行为,例如“

<configuration>
    <runtime>
        <ThrowUnobservedTaskExceptions enabled=”true”/>
    </runtime>
</configuration>

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

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