【问题标题】:Runtime exception catching different between inside and outside of MSVS在 MSVS 内部和外部捕获不同的运行时异常
【发布时间】:2011-11-27 10:05:00
【问题描述】:

我在程序中的某个地方调用以下函数会引发异常

public static List<Templates> LoadTemplates()
{
    // ...
    // System.Threading.Thread.CurrentThread.ManagedThreadId == 1 // ID written to log file
    System.IO.Directory.GetFiles("does_not_exist_directory");
    // ...
}

我尝试在默认 Program.cs 中捕获异常

try
{
    // System.Threading.Thread.CurrentThread.ManagedThreadId == 1
    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);
    Application.Run(new Form1());
}
catch (Exception ex)
{
    MessageBox.Show("ERROR CAUGHT");
}
finally { // do clean up }

在 MSVS 中运行时,异常会按预期捕获。但是当通过双击输出目录中的 .exe 运行时,异常会显示在消息对话框中,说明

编辑:

要在从输出目录运行 .exe 时捕获错误,必须在编译代码时处理 Application.ThreadException 事件

Application.ThreadException += new System.Threading.ThreadExceptionEventHandler(Application_ThreadException);
Application.Run(new Form());

但随后 MSVS 将通过显示 MSVS 本机“故障排除提示”无边界消息对话框“未处理的异常”来表现不良。

如何确保它在 MSVS 内外的行为相同?

【问题讨论】:

标签: c# exception


【解决方案1】:

您展示的代码只会在同一个线程中捕获异常。如果没有看到有问题的代码及其上下文,真的很难判断。

您可以订阅几个事件来捕获所有这些:

请阅读/注意文档(第一个应该这样做)- 有一些警告。

【讨论】:

  • 我真的不认为代码在另一个线程中运行,除非静态单例 + 静态类方法调用导致某种线程调用?或者调用另一个 Form 反过来调用这个 LoadTemplate 也等于线程调用?
【解决方案2】:

看起来您的 LoadTemplates 调用是在自己的线程中进行的。我假设您在调试模式下看不到 MessageBox。您将看到 Visual Studio 异常窗口。

要解决此问题,请尝试使用 AppDomain.CurrentDomain.UnhandledException 事件:

[STAThread]
static void Main() {
    Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
    AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);

    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);
    Application.Run(new Form1());
}

static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e) {
    MessageBox.Show("Unhandled exception");
}

【讨论】:

  • 我认为这行不通。在 MSVS 中运行时,现在不会出现上述对话框。但该异常仍未通过 MSVS 本机异常断点故障排除提示框处理,标题为“DirectoryNotFoundException 未被用户代码处理”
  • 在没有指定异常的情况下使用catch块时是否捕获到异常? try{...} catch {...}
  • 在 MSVS 运行中使用 try/catch 捕获异常(F5 开始调试),带或不带“Exception e”参数。
  • 异常似乎被 Application.Run() 捕获。在Application.Run()之前添加Application.ThreadException += new ThreadExceptionEventHandler(Application_ThreadException);时你能抓住它吗
  • 您甚至可以从静态代码中调用 woni 的建议行,以增加在调试器中捕获异常的机会
【解决方案3】:

关于 MSVS 内外的异常行为,Carsten 将我指向 MSDN 中的代码是正确的,但 woni 帮助我更好地了解情况。

(可能不是这样,但是)当从 MSVS 内部运行时,MSVS 似乎将其内部事件处理程序挂钩到应用程序,并且该处理程序在应用程序中我的处理程序之前运行。因此,当发生未处理的异常时,MSVS 将显示其原生的“故障排除提示”对话框,指向错误行。

此时,如果我点击继续(F5)继续执行代码,MSVS 将重新抛出异常,这一次它会被我自己的处理程序捕获。

在 MSVS 之外,没有订阅其他处理程序,因此它只是直接运行我的处理程序。

【讨论】:

    猜你喜欢
    • 2013-05-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多