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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2014562/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 22:41:04  来源:igfitidea点击:

What's the difference between Application.ThreadException and AppDomain.CurrentDomain.UnhandledException?

c#.netwinformsexception-handling

提问by JohnIdol

Alright, this is an easy one:

好吧,这是一个简单的:

  • What's the difference between Application.ThreadExceptionand
    AppDomain.CurrentDomain.UnhandledException?

  • Do I need to handle both?

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

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

Thanks!

谢谢!

采纳答案by Hans Passant

Application.ThreadException is specific to Windows Forms. Winforms runs event handlers in response to messages sent to it by Windows. The Click event for example, I'm sure you know them. If such an event handler throws an exception then there's a back-stop inside the Winforms message loop that catches that exception.

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

That backstop fires the Application.ThreadExceptionevent. If you don't override it, the user will get a ThreadExceptionDialog. Which allows him to ignore the exception and keep running your program. Not a great idea btw.

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

You can disable this behavior by calling Application.SetUnhandledExceptionMode()in the Main() method in Program.cs. Without that backstop in place, the usual thing happens when a thread dies from an unhandled exception: AppDomain.UnhandledExceptionfires and the program terminates.

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

Fwiw: "ThreadException" was a very poor name choice. It has nothing to do with threads.

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

回答by Joshua Cauble

Well the thing is, ThreadExceptionoccurs due to a problem with your thread, the Unhandled Exceptionis fired if you code throws an exception that is not handled.

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

Easist way to cause the second one is to create an app with no try...catch blocks and throw an exception.

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

Now if you need insurance you can handle them both, however if you capture and handle your exceptionscorrectly then you should not need the UnhandledExceptionhandler as it's kind of like a catch all.

现在,如果您需要保险,您可以同时处理它们,但是如果您exceptions正确捕获和处理,那么您就不需要UnhandledException处理程序,因为它有点像一个包罗万象的东西。

回答by JohnIdol

OK - I had it in front of me, this bit of code from msdnis pretty self-explanatory:

好的 - 我在我面前,来自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());
}

回答by serhio

From source:

来源

In applications that use Windows Forms, unhandled exceptions in the main application thread cause the Application.ThreadExceptionevent to be raised. If this event is handled, the default behavior is that the unhandled exception does not terminate the application, although the application is left in an unknown state. In that case, the UnhandledExceptionevent is not raised. This behavior can be changed by using the application configuration file, or by using the Application.SetUnhandledExceptionModemethod to change the mode to UnhandledExceptionMode.ThrowExceptionbefore the ThreadExceptionevent handler is hooked up. This applies only to the main application thread. The UnhandledExceptionevent is raised for unhandled exceptions thrown in other threads.

Starting with Visual Studio 2005, the Visual Basicapplication framework provides another event for unhandled exceptions in the main application thread - WindowsFormsApplicationBase.UnhandledException. This event has an event arguments object with the same name as the event arguments object used by AppDomain.UnhandledException, but with different properties. In particular, this event arguments object has an ExitApplicationproperty that allows the application to continue running, ignoring the unhandled exception (and leaving the application in an unknown state). In that case, the AppDomain.UnhandledException event is not raised.

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

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

Application.ThreadExceptioncan be caught and the application could continue(in general is not a great idea, but for the application like running periodically some actions this is a good solution).

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

To catch exceptions that occur in threads not created and owned by Windows Forms, use the AppDomain.UnhandledException. It allows the application to log information about the exception before the system default handler reports the exception to the user and terminates the application.
The handling of this exception does not prevent application to be terminated.
The maximum that could be done(program data can become corrupted when exceptions are not handled) is saving program data for later recovery. After that the application domain is unloaded and the application terminates.

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

Starting with the .NET 4, this event is not raised for exceptions that corrupt the state of the process, such as stack overflows or access violations, unless the event handler is security-critical and has the HandleProcessCorruptedStateExceptionsAttributeattribute.

.NET 4开始,对于破坏进程状态的异常,例如堆栈溢出或访问冲突,不会引发此事件,除非事件处理程序对安全性至关重要并且具有该HandleProcessCorruptedStateExceptionsAttribute属性。

For more details, see MSDN.

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