【问题标题】:Catching exception in Main() method在 Main() 方法中捕获异常
【发布时间】:2011-02-12 19:46:38
【问题描述】:

考虑以下简单的应用程序:由 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 并启动可执行文件,我会看到标准的“未处理异常”窗口,这意味着我的异常处理程序不起作用。

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

【问题讨论】:

  • @Corvin:如果您觉得您的问题有解决方案,请检查已接受的答案。

标签: c# .net windows visual-studio winforms


【解决方案1】:

通常 Application.ThreadException 将在 Load 事件中处理异常。您将获得提供退出和继续选项的 ThreadExceptionDialog。

但不是在附加调试器时。在这种情况下,有意禁用显示对话框的消息循环中的 catch 子句。这是必要的,因为如果在调试程序时弹出该对话框,则很难对异常进行故障排除。如果这个捕手不再活动,您在 Main() 方法中的 catch 子句现在可以处理异常。

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

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

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

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

【讨论】:

  • @Hans - 你指的是Form.Load 事件吗?顺便说一句,写得很好。
【解决方案2】:

除了捕获Main 方法中抛出的任何异常之外,您还必须处理AppDomain.CurrentDomain.UnhandledExceptionApplication.ThreadException

不确定为什么在附加和不附加调试器的情况下行为会有所不同。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-23
    • 2010-09-26
    相关资源
    最近更新 更多