8

我不确定这是否是正确的地方,但无论如何我会的。

我有 2 个 .NET 应用程序;一个是我自己编译的,另一个不是。两者都使用 .NET Framework 4.5。但是他们处理异常的方式不同。

在我没有编译的应用程序中;它显示了未处理的异常对话框(我想要并期望)

来自我没有编译的应用程序的未处理异常

但是在我编译的应用程序中;它只是显示应用程序已崩溃;

我编译的应用程序中未处理的异常

因此,VS 配置或项目配置中必须有一个设置阻止未处理的异常对话框显示在我编译的应用程序中?...

我尝试重新安装 VS,更改 Debug->Exceptions 菜单中的设置,但都没有工作...

4

2 回答 2

12

上面的屏幕截图是一个 ThreadExceptionDialog。它显示在非常特殊的情况下,即 Winforms 应用程序在消息循环 (Application.Run) 触发的事件处理程序中爆炸,并且应用程序没有重新分配 Application.ThreadException 事件处理程序。使用它不是一个很好的做法,用户没有合理的方法可以知道是单击继续还是退出按钮。请务必调用 Application.SetUnhandledExceptionMode() 来禁用它。

底部的屏幕截图是默认的 Windows 错误报告对话框,当程序因未处理的异常而被轰炸时,Windows 会显示该对话框。你不应该让它达到这一点,对话框没有显示足够的信息来帮助任何人诊断和解决问题。始终为 AppDomain.CurrentDomain.UnhandledException 事件编写事件处理程序。显示和/或记录 e.ExceptionObject.ToString() 并调用 Environment.Exit() 以终止应用程序。

使您的 Program.cs 源代码看起来与此类似:

    [STAThread]
    static void Main() {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.SetUnhandledExceptionMode(UnhandledExceptionMode.ThrowException);
        AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
        Application.Run(new Form1());
    }

    static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e) {
        // TODO: improve logging and reporting
        MessageBox.Show(e.ExceptionObject.ToString());
        Environment.Exit(-1);
    }
于 2012-07-21T09:59:29.947 回答
2

Hans Passant 提出的解决方案将终止应用程序。这也意味着finally不再执行剩余的块。

您还可以使用 PInvoke 通过调用该SetErrorMode()方法来更改行为。

public enum ErrorModes : uint
{
    SYSTEM_DEFAULT = 0x0,
    SEM_FAILCRITICALERRORS = 0x0001,
    SEM_NOALIGNMENTFAULTEXCEPT = 0x0004,
    SEM_NOGPFAULTERRORBOX = 0x0002,
    SEM_NOOPENFILEERRORBOX = 0x8000,
    SEM_NONE = SEM_FAILCRITICALERRORS | SEM_NOALIGNMENTFAULTEXCEPT | SEM_NOGPFAULTERRORBOX | SEM_NOOPENFILEERRORBOX
}

[DllImport("kernel32.dll")]
static extern ErrorModes SetErrorMode(ErrorModes uMode);

然后打电话

SetErrorMode(ErrorModes.SEM_NONE);

这样做会给finally积木运行的机会。

于 2017-09-17T20:05:33.453 回答