C# 在Main()方法中捕获异常

C# 在Main()方法中捕获异常,c#,.net,windows,visual-studio,winforms,C#,.net,Windows,Visual Studio,Winforms,考虑以下简单的应用程序:由VS中的“新C#windows应用程序”序列创建的windows窗体,该窗体以以下方式修改: public static void Main() { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); try { Application.Run(new Form1()); } cat

考虑以下简单的应用程序:由VS中的“新C#windows应用程序”序列创建的windows窗体,该窗体以以下方式修改:

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包含以下修改:

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

}
如果我在IDE中按F5,那么,正如我预期的那样,我会看到一个消息框,说异常被捕获,应用程序退出

如果我转到Debug(或Release)/bin并启动可执行文件,我会看到标准的“Unhandled exception”窗口,这意味着我的异常处理程序无法工作

显然,这与从调用Application.Run的另一个线程抛出异常有关。但问题仍然存在——为什么行为会因应用程序是从IDE还是从命令行运行而有所不同?
确保应用程序中没有未处理的异常的最佳实践是什么?

除了捕获在
Main
方法中抛出的任何异常之外,您还必须处理和


但是,不确定在附加调试程序和未附加调试程序的情况下,行为为何不同。

通常情况下,Application.ThreadException将在加载事件中处理异常。您将获得ThreadExceptionDialog,它提供了退出和继续选项

但在附加调试器时不会。在这种情况下,消息循环中显示对话框的catch子句被故意禁用。这是必要的,因为如果调试程序时弹出对话框,则很难排除异常。如果此catcher不再处于活动状态,那么Main()方法中的catch子句现在可以捕获异常

可以通过在Main()方法中使用Application.SetUnhandledExceptionMode()使其一致。您不应该这样做,如果您这样做,异常真的很难调试。如果要自定义UI线程的异常处理,则应注册自己的应用程序。线程异常处理程序:

  if (!System.Diagnostics.Debugger.IsAttached)
    Application.ThreadException += myThreadException;
在工作线程中捕获未处理的异常需要AppDomain.UnhandledException处理程序。它们是不可恢复的


还要注意64位Windows中的错误,当附加调试器时,加载事件中的异常会在没有诊断的情况下被吞噬。强制任何CPU模式以避免该陷阱。

@Corvin:如果您觉得您的问题有解决方案,请检查已接受的答案。@Hans-您指的是
表单.Load
事件吗?顺便说一句,写得不错。