在主要捕捉异常()方法异常、方法

2023-09-03 16:55:23 作者:借个拥抱

考虑下面的简单应用:

public static void Main()
{
    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);

    try
    {
        Application.Run(new Form1());
    }
    catch (Exception ex)
    {
        MessageBox.Show("An unexpected exception was caught.");
    }

}

Form1.cs中包含了以下修改:

Form1.cs contains the following modifications:

private void Form1_Load(object sender, EventArgs e)
{
    throw new Exception("Error");

}

如果我在IDE preSS F5的话,如我所料,我看到一个消息框,说异常被抓获,并在应用程序退出。

If I press F5 in IDE, then, as I expect, I see a message box saying that exception was caught and the application quits.

如果我去调试(或释放)/ bin并启动可执行文件,我看到了标准的未处理的异常的窗口,这意味着我的异常处理程序无法正常工作。

If I go to Debug(or Release)/bin and launch the executable, I see the standard "Unhandled exception" window, meaning that my exception handler doesn't work.

显然,有事情做与例外从不同的线程Application.Run是从所谓的被抛出。但问题是 - 为什么行为不同取决于应用程序已经运行从IDE或命令行? 什么是最好的做法,以确保没有异常仍未处理的应用程序?

Obviously, that has something to do with exception being thrown from a different thread that Application.Run is called from. But the question remains - why the behavior differs depending on whether the application has been run from IDE or from command line? What is the best practice to ensure that no exceptions remain unhandled in the application?

推荐答案

通常Application.ThreadException会处理这个异常的Load事件。你会得到ThreadExceptionDialog,提供了退出并继续选项。

Normally Application.ThreadException will handle the exception in the Load event. You'll get the ThreadExceptionDialog that offers the Quit and Continue options.

而不是当一个调试器附加。在显示的对话框中的消息循环的catch子句在这种情况下,故意禁用。这是必要的,因为如果对话框弹出时,调试程序将是非常困难的麻烦拍摄例外。此捕手不再活跃,在main()方法的catch子句现在得到了一枪在异常。

But not when a debugger is attached. The catch clause in the message loop that displays the dialog is intentionally disabled in that case. That's necessary because it would be very difficult to trouble-shoot exceptions if that dialog pops up when you debug a program. Which this catcher no longer active, your catch clause in the Main() method now gets a shot at the exception.

您可以通过在main()方法来Application.SetUnhandledExceptionMode()是一致的。你不应该,真的异常的是的硬盘,如果你这样做是为了调试。如果您想自定义异常处理的UI线程,那么你应该注册您自己Application.ThreadException处理程序:

You can make it consistent by using Application.SetUnhandledExceptionMode() in the Main() method. You shouldn't, exceptions really are hard to debug if you do this. If you want to customize exception handling for the UI thread then you should register your own Application.ThreadException handler:

  if (!System.Diagnostics.Debugger.IsAttached)
    Application.ThreadException += myThreadException;

捕获未处理异常的工作线程需要AppDomain.UnhandledException处理程序。他们是不可恢复的。

Trapping unhandled exceptions in worker threads requires a AppDomain.UnhandledException handler. They are not recoverable.

另外注意在64位Windows中的错误,在负载情况下的例外是吞食无诊断时,调试器附加。强制值为anycpu模式,以避免这些陷阱。

Also beware of a bug in 64-bit Windows, exceptions in the Load event are swallowed without diagnostic when a debugger is attached. Force AnyCPU mode to avoid that trap.

 
精彩推荐
图片推荐