Application.ThreadException和AppDomain.CurrentDomain.UnhandledException有什么区别?


107

好吧,这很简单:

  • Application.ThreadException和之间有什么区别
    AppDomain.CurrentDomain.UnhandledException

  • 我需要同时处理两者吗?

谢谢!

Answers:


98

Application.ThreadException特定于Windows窗体。Winforms运行事件处理程序以响应Windows发送给它的消息。例如,单击事件,我确定您了解它们。如果此类事件处理程序引发异常,则Winforms消息循环中将存在一个捕获该异常的后台程序。

该支持会触发Application.ThreadException事件。如果您不重写它,则用户将获得ThreadExceptionDialog。这使他可以忽略异常并继续运行您的程序。顺便说一句,这不是一个好主意。

您可以通过在Program.cs的Main()方法中调用Application.SetUnhandledExceptionMode()来禁用此行为。没有适当的支持,当线程因未处理的异常而死亡时,会发生通常的事情:AppDomain.UnhandledException触发并且程序终止。

Fwiw:“ ThreadException”是一个非常糟糕的名称选择。它与线程无关。


以及如何防止WinForms应用程序崩溃的发生Application.ThreadException。我用小的C#代码对此[这里 ] 提出了一个问题。
Mahesha999

2
鉴于winforms绑定到单个线程,因此我始终将其视为应用程序线程异常。
2014年

36

来自来源

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

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

Application.ThreadException可能会被捕获并且应用程序可以继续运行(通常不是一个好主意,但是对于像定期运行某些操作这样的应用程序来说,这是一个很好的解决方案)。

要捕获非Windows窗体创建和拥有的线程中发生的异常,请使用AppDomain.UnhandledException。它允许应用程序在系统默认处理程序向用户报告异常并终止应用程序之前记录有关异常的信息。
处理此异常不会阻止应用程序终止。
可以做的最大工作(不处理异常时程序数据可能会损坏)正在保存程序数据以供以后恢复。之后,将应用程序域卸载并终止应用程序。

.NET 4开始,除非破坏事件处理程序具有安全性并具有HandleProcessCorruptedStateExceptionsAttribute 属性,否则不会破坏进程状态的异常(例如,堆栈溢出或访问冲突)时引发此事件。

有关更多详细信息,请参见MSDN


18

好的-我已经知道了,来自msdn的这段代码非常不言自明:

public static void Main(string[] args)
{
    // Add the event handler for handling UI thread exceptions to the event.
    Application.ThreadException += new 
        ThreadExceptionEventHandler(ErrorHandlerForm.Form1_UIThreadException);

    // Set the unhandled exception mode to force all Windows Forms 
    // errors to go through our handler.
    Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);

    // Add the event handler for handling non-UI thread exceptions to the event. 
    AppDomain.CurrentDomain.UnhandledException +=
        new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);

    // Runs the application.
    Application.Run(new ErrorHandlerForm());
}

3
这与serhio的其他回答相反:他说:UnhandledExceptionMode.ThrowException应该在连接ThreadException事件处理程序之前设置。不知道命令是否真的重要……
Davide Piras

@DavidePiras是的,还有一些更模糊的东西。SetUnhandledException似乎没有什么不同。
nawfal 2014年

0

好的事情是,ThreadException由于线程问题而发生,Unhandled Exception如果您的代码抛出未处理的异常,则会触发。

导致第二种错误的简便方法是创建一个没有try ... catch块并引发异常的应用程序。

现在,如果您需要保险,则可以同时处理这两种保险,但是,如果您exceptions正确地捕获并处理了保险,那么就不需要UnhandledException处理程序了,因为这有点像万能险。


谢谢-我不太清楚的是,如果要处理UnhandledException,我也会捕获ThreadException-情况似乎并非如此
JohnIdol 2010年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.