在 .NET 中,如果主线程发生了一个异常而未被try/catch
捕获的话则会弹出一个错误对话框,报告该异常的信息:
用户可以点击详细信息
按钮,将其中的内容提供给开发者,帮助开发者排查问题。同时允许用户继续运行程序。
未处理异常事件
在 .NET 中,有两个事件可以处理未处理异常:
- Application.ThreadException。仅适用于 WinForms 程序,只能处理主线程异常,且程序可以继续运行。
- AppDomain.UnhandledException。
两者的区别很明显,ThreadException 是 WinForms 程序特定的,只处理 UI 线程的异常,并且程序允许不退出。
而 UnhandledException 是真正意义上的未处理异常处理事件。
1 | internal static class Program |
设置异常处理模式
通过 Application.SetUnhandledExceptionMode 方法指定异常处理模式。
参数是一个 UnhandledExceptionMode 类型。
值 | 说明 |
---|---|
Automatic | 将所有异常都传送到 ThreadException 处理程序,除非应用程序的配置文件指定了其他位置。 |
ThrowException | 从不将异常传送到 ThreadException 处理程序。 忽略应用程序配置文件。 |
CatchException | 始终将异常传送到 ThreadException 处理程序。 忽略应用程序配置文件。 |
简单说,处理模式就是决定主线程异常要不要交给 UnhandledException 事件处理。
通过配置文件指定异常处理模式
这些选项都提到了应用程序配置文件,用文件是这样配置的:
1 |
|
这个配置等同于在程序中使用:
1 | Application.SetUnhandledExceptionMode(UnhandledExceptionMode.ThrowException); |
不过这个配置文件选项只有在没有指定 ThreadException 处理程序时有效。
看一个例子:
1 | static void Main() |
根据 Automatic 的作用,未处理异常应该在 ThreadException 中处理,但由于配置了<system.windows.forms jitDebugging="true"/>
,导致异常交给了 UnhandledException 来处理。
如果想忽略配置文件的设置,应该将模式改为UnhandledExceptionMode.CatchException
。
对于这个文件配置,了解一下即可,几乎不会用到。
legacyUnhandledExceptionPolicy
legacyUnhandledExceptionPolicy
配置可以防止工作线程未处理异常后强制退出。
1 |
|
总结
- ThreadException 这个名字有点迷惑,实际它就是主线程异常处理事件。
- 对于异常处理模式,Automatic 是默认值,不需要显示指定。CatchException 和 Automatic 作用相同,只是忽略配置文件,而配置文件基本不会用到,所以当我们要显示指定处理模式时,基本就是设置为 ThrowException。
相关阅读
Application.ThreadException 和 AppDomain.CurrentDomain.UnhandledException 之间有什么区别?
当 UnhandledExceptionMode 设置为 UnhandledExceptionMode.Automatic 时,哪个 .config 元素会影响异常处理?
配置 legacyUnhandledExceptionPolicy 防止后台线程抛出的异常让程序崩溃退出