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

时间:2010-01-06 16:48:05

标签: c# .net winforms exception-handling

好的,这很简单:

  • Application.ThreadException AppDomain.CurrentDomain.UnhandledException 之间的区别是什么?

  • 我需要同时处理吗?

谢谢!

4 个答案:

答案 0 :(得分:96)

Application.ThreadException特定于Windows窗体。 Winforms运行事件处理程序以响应Windows发送给它的消息。例如,Click事件,我相信你知道它们。如果这样的事件处理程序抛出异常,那么Winforms消息循环中会有一个后退停止捕获该异常。

该后盾发起Application.ThreadException事件。如果您不覆盖它,用户将获得ThreadExceptionDialog。这允许他忽略异常并继续运行程序。不是一个好主意。

您可以通过调用Program.cs中Main()方法中的Application.SetUnhandledExceptionMode()来禁用此行为。如果没有该止回器,当线程从未处理的异常中死亡时,通常会发生这种情况:AppDomain.UnhandledException触发并且程序终止。

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

答案 1 :(得分:34)

在使用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

答案 2 :(得分: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 :(得分:0)

嗯,问题是ThreadException由于你的线程出现问题而发生,如果你的代码抛出了一个未处理的异常,就会触发Unhandled Exception

导致第二种方法的简单方法是创建一个没有尝试的应用程序... catch块并抛出异常。

现在,如果您需要保险,您可以同时处理它们,但是如果您正确捕获和处理exceptions,那么您不应该需要UnhandledException处理程序,因为它有点像捕获所有。