System.AppDomain.UnhandledException 事件

本文提供了此 API 参考文档的补充说明。

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

可以在任何应用程序域中处理此事件。 但是,在发生异常的应用程序域中不一定引发该事件。 仅当线程的整个堆栈未找到适用的异常处理程序时,才会撤消异常,因此可以引发事件的第一个位置位于发起线程的应用程序域中。

UnhandledException如果事件在默认应用程序域中进行处理,则会在任何线程中引发任何未经处理的异常,无论线程启动的应用程序域是什么。 如果线程在具有事件处理程序 UnhandledException的应用程序域中启动,则会在该应用程序域中引发该事件。 如果该应用程序域不是默认应用程序域,并且默认应用程序域中也有事件处理程序,则会在这两个应用程序域中引发该事件。

例如,假设线程在应用程序域“AD1”中启动,在应用程序域“AD2”中调用方法,并从中调用应用程序域“AD3”中的方法,其中引发异常。 可以引发事件的第一个应用程序域 UnhandledException 是“AD1”。 如果该应用程序域不是默认应用程序域,则还可以在默认应用程序域中引发该事件。

注意

公共语言运行时在执行事件的事件处理程序 UnhandledException 时挂起线程中止。

如果事件处理程序具有具有 ReliabilityContractAttribute 相应标志的属性,则事件处理程序被视为受约束的执行区域。

从 .NET Framework 4 开始,对于损坏进程状态(如堆栈溢出或访问冲突)的异常,不会引发此事件,除非事件处理程序是安全关键且具有 HandleProcessCorruptedStateExceptionsAttribute 属性。

若要为此事件注册事件处理程序,必须具有所需的权限或引发权限 SecurityException

有关处理事件的详细信息,请参阅 处理和引发事件

未处理的异常的其他事件

对于某些应用程序模型,如果未处理的异常发生在主应用程序线程中, UnhandledException 事件可能会被其他事件抢占。

在使用Windows 窗体的应用程序中,主应用程序线程中的未经处理的异常会导致Application.ThreadException引发事件。 如果处理此事件,则默认行为是未经处理的异常不会终止应用程序,尽管应用程序处于未知状态。 在这种情况下, UnhandledException 不会引发该事件。 此行为可以通过使用应用程序配置文件进行更改,或者通过使用 Application.SetUnhandledExceptionMode 方法将模式 UnhandledExceptionMode.ThrowException 更改为在事件处理程序挂钩之前 ThreadException 。 这仅适用于主应用程序线程。 对于在其他线程中引发未经处理的异常,将引发该 UnhandledException 事件。

Visual Basic 应用程序框架为主应用程序线程(该 WindowsFormsApplicationBase.UnhandledException 事件)中的未经处理的异常提供了另一个事件。 此事件具有与事件 AppDomain.UnhandledException参数对象相同的名称的事件参数对象,但具有不同的属性。 具体而言,此事件参数对象具有一个 ExitApplication 属性,该属性允许应用程序继续运行,忽略未经处理的异常(并使应用程序处于未知状态)。 在这种情况下, AppDomain.UnhandledException 不会引发该事件。