AppDomain.UnhandledException 会自动重新引发已处理的异常

本文关键字:处理 异常 新引发 UnhandledException AppDomain | 更新日期: 2023-09-27 17:57:17

>我正在尝试捕获应用程序中所有未处理的异常,以便有条件地处理那些可以在不终止应用程序的情况下发生的异常,但我无法解决一个非常基本的问题:它不会停止异常。在代码中的某个位置抛出一个未经处理的异常,它来到这里,显示消息框,然后应用程序要么显示相同的异常未处理(如果在调试模式下)要么只是崩溃(如果在没有调试的情况下运行)。这意味着即使调用了处理程序,异常也会保持未处理状态。

App() {
    AppDomain.CurrentDomain.UnhandledException += (s, a) => {
        var ex = (Exception)a.ExceptionObject;
        MessageBox.Show(ex.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
    };
}

这是来自一个新的空白测试项目,除了此代码和一个在单击时引发异常的按钮之外,该项目中没有任何内容。

AppDomain.UnhandledException 会自动重新引发已处理的异常

你忘了终止你的程序。 因此,它继续正常的未经处理的异常处理。 添加此行:

  Environment.Exit(System.Runtime.InteropServices.Marshal.GetHRForException(ex));

稍微费力的封送调用可确保获取进程的 Process.ExitCode 的另一个进程获得合理的错误指示。 它是可选的,只是推荐。

来自 MSDN:

此事件提供未捕获异常的通知。它允许应用程序在系统默认处理程序向用户报告异常并终止应用程序之前记录有关异常的信息。如果有关应用程序状态的足够信息可用,则可以执行其他操作,例如保存程序数据以供以后恢复。建议谨慎,因为在未处理异常时,程序数据可能会损坏。

换句话说,它只是一个处理程序,允许您告诉用户发生了什么,如果您需要能够恢复数据,则生成最后一分钟的保存信息,或者执行诸如触发自定义错误报告之类的操作。 它不是一个捕获块。 要捕获异常,您必须使用 Try-Catch。

如果这确实是您想要的行为,则可以将以下内容添加到应用程序配置文件中:

<legacyUnhandledExceptionPolicy enabled="1"/>

请参阅托管线程中的异常。

它不应该"停止"异常,该行为是设计使然:

此事件提供未捕获异常的通知。它允许应用程序在系统默认处理程序向用户报告异常并终止应用程序之前记录有关异常的信息。

考虑到这个地方,如果没有其他人费心处理有问题的异常,除了记录和死亡之外,没有什么明智的做法可做。

您应该处理那些应该在更接近它们发生的位置终止应用程序的异常。

您实际上并没有捕获未处理的异常,而只是处理在终止应用程序之前发生的事件(在发布模式下)。订阅此事件不计为捕获已未处理的异常。

从 MSDN:此事件提供未捕获异常的通知。它允许应用程序在系统默认处理程序向用户报告异常并终止应用程序之前记录有关异常的信息。如果有关应用程序状态的足够信息可用,则可以执行其他操作,例如保存程序数据以供以后恢复。建议谨慎,因为在未处理异常时,程序数据可能会损坏。