Module Example
Sub Main()
Dim currentDomain As AppDomain = AppDomain.CurrentDomain
AddHandler currentDomain.UnhandledException, AddressOf MyHandler
Throw New Exception("1")
Catch e As Exception
Console.WriteLine("Catch clause caught : " + e.Message)
Console.WriteLine()
End Try
Throw New Exception("2")
End Sub
Sub MyHandler(sender As Object, args As UnhandledExceptionEventArgs)
Dim e As Exception = DirectCast(args.ExceptionObject, Exception)
Console.WriteLine("MyHandler caught : " + e.Message)
Console.WriteLine("Runtime terminating: {0}", args.IsTerminating)
End Sub
End Module
' The example displays the following output:
' Catch clause caught : 1
' MyHandler caught : 2
' Runtime terminating: True
' Unhandled Exception: System.Exception: 2
' at Example.Main()
此事件提供未捕获异常的通知。 它允许应用程序在系统默认处理程序向用户报告异常并终止应用程序之前记录有关异常的信息。 如果提供了有关应用程序状态的足够信息,可能会执行其他操作,例如保存程序数据以供以后恢复。 建议谨慎,因为未处理异常时,程序数据可能会损坏。
在.NET Framework版本 1.0 和 1.1 中,应用程序终止和调试选项在引发此事件之前而不是之后报告给用户。
可以在任何应用程序域中处理此事件。 但是,事件不一定在发生异常的应用程序域中引发。 仅当线程的整个堆栈已展开且未找到适用的异常处理程序时,才会取消处理异常,因此可以引发事件的第一个位置是发起线程的应用程序域中。
在 .NET Framework版本 1.0 和 1.1 中,此事件仅针对启动应用程序时由系统创建的默认应用程序域发生。 如果应用程序创建其他应用程序域,则为这些应用程序域中的此事件指定委托不起作用。
UnhandledException
如果在默认应用程序域中处理事件,则会在任何线程中引发任何未经处理的异常,无论线程在哪个应用程序域中启动。 如果线程在具有 的
UnhandledException
事件处理程序的应用程序域中启动,则会在该应用程序域中引发该事件。 如果该应用程序域不是默认应用程序域,并且默认应用程序域中还有一个事件处理程序,则会在两个应用程序域中引发该事件。
例如,假设一个线程在应用程序域“AD1”中启动,调用应用程序域“AD2”中的方法,并从该位置调用应用程序域“AD3”中的方法,其中会引发异常。 可以在其中
UnhandledException
引发事件的第一个应用程序域是“AD1”。 如果该应用程序域不是默认应用程序域,也可以在默认应用程序域中引发该事件。
当事件的事件处理程序
UnhandledException
正在执行时,公共语言运行时挂起线程中止。
如果事件处理程序具有
ReliabilityContractAttribute
具有相应标志的属性,则事件处理程序被视为受约束的执行区域。
从.NET Framework 4 开始,除非事件处理程序是安全关键且具有
HandleProcessCorruptedStateExceptionsAttribute
属性,否则不会针对损坏进程状态的异常(如堆栈溢出或访问冲突)引发此事件。
在 .NET Framework版本 1.0 和 1.1 中,main应用程序线程以外的线程中发生的未经处理的异常被运行时捕获,因此不会导致应用程序终止。 因此,可以在
UnhandledException
不终止应用程序的情况下引发 事件。 从 .NET Framework 版本 2.0 开始,删除了子线程中未经处理的异常的此后备,因为此类无提示故障的累积影响包括性能下降、数据损坏和锁定,所有这些都难以调试。 有关详细信息,包括运行时不终止的情况列表,请参阅
托管线程中的异常
。
若要为此事件注册事件处理程序,必须具有所需的权限,否则
SecurityException
会引发 。
有关处理事件的详细信息,请参阅
处理和引发事件
。
未经处理的异常的其他事件
对于某些应用程序模型,
UnhandledException
如果main应用程序线程中发生未经处理的异常,该事件可能会被其他事件抢占。
在使用 Windows 窗体 的应用程序中,main应用程序线程中未经处理的异常会导致
Application.ThreadException
引发 事件。 如果处理此事件,则默认行为是未经处理的异常不会终止应用程序,尽管应用程序处于未知状态。 在这种情况下,
UnhandledException
不会引发 事件。 可以使用应用程序配置文件更改此行为,或使用
Application.SetUnhandledExceptionMode
方法在事件处理程序挂接之前
ThreadException
将模式
UnhandledExceptionMode.ThrowException
更改为 。 这仅适用于main应用程序线程。 对于在其他线程中引发的未经处理的异常,将
UnhandledException
引发 该事件。
从 Microsoft Visual Studio 2005 开始,Visual Basic 应用程序框架为main应用程序线程中的未经处理的异常提供另一个事件。
WindowsFormsApplicationBase.UnhandledException
请参阅 事件。 此事件具有一个事件参数对象,其名称与 所使用的
AppDomain.UnhandledException
事件参数对象相同,但具有不同的属性。 具体而言,此事件参数对象具有一个
ExitApplication
属性,该属性允许应用程序继续运行,忽略未处理的异常 (并使应用程序) 处于未知状态。 在这种情况下,
AppDomain.UnhandledException
不会引发 事件。