为什么 .NET 异常没有被 try/catch 块捕获?

我正在使用 C 的 ANTLR 解析器库开发一个项目

请先 登录 后评论

6 个回答

Daniel Auger

是否有可能在另一个线程中抛出异常?显然,您的调用代码是单线程的,但您正在使用的库可能正在执行一些多线程操作。

请先 登录 后评论
ljs

无论程序集是否已编译为发布版本,异常肯定会“冒泡”到调用者,没有理由没有在调试模式下编译的程序集对此有任何影响。

我同意 Daniel 的建议,即异常可能发生在单独的线程上 - 尝试在 Application.ThreadException 中挂钩线程异常事件。当发生任何未处理的线程异常时,应该引发此问题。您可以这样调整您的代码:-

using System.Threading;

...

void Application_ThreadException(object sender, ThreadExceptionEventArgs e) {
  throw new ParserException(e.Exception.Message, e.Exception);
}    

 ...

 var exceptionHandler = 
    new ThreadExceptionEventHandler(Application_ThreadException);
 Application.ThreadException += exceptionHandler;
 try {
    // Execution stopped at parser.prog()
    TimeDefParser.prog_return prog_ret = parser.prog();
    return prog_ret == null ? null : prog_ret.value;
 }
 catch (Exception ex) {
    throw new ParserException(ex.Message, ex);
 }
 finally {
    Application.ThreadException -= exceptionHandler;
 }
请先 登录 后评论
ljs

哦,关于基比所说的;如果您在 VS 中选择 Debug|Exceptions 并单击“抛出”列中的所有框,它应该选择 所有内容 AFAIK 作为“第一次机会异常”,即 VS 将指示异常何时 < em>about 将由其他所有内容处理并中断相关代码。这应该有助于调试。

请先 登录 后评论
Quibblesome
<块引用>

“另外,你可以把一些代码 捕获所有未处理的异常。读 更多信息的链接,但基础知识 是这两行。”

这是错误的。这曾经在 .NET 1.0/1.1 中捕获所有未处理的异常,但这是一个错误,不应该这样做,它已在 .NET 2.0 中修复。

AppDomain.CurrentDomain.UnhandledException 

仅打算用作最后机会记录沙龙,以便您可以在程序退出之前记录异常。从 2.0 开始,它不会捕获异常(尽管在 .NET 2.0 中至少有一个配置值可以修改以使其表现得像 1.1,但不建议使用它。)。

值得注意的是,您无法捕获的异常很少,例如 StackOverflowException 和 OutOfMemoryException。否则,正如其他人所建议的那样,它可能是某个后台线程中的异常。此外,我很确定您也无法捕获一些/所有非托管/本机异常。

请先 登录 后评论
Mark Brackett

我不明白...您的 catch 块只是抛出一个新异常(带有相同的消息)。这意味着您的声明:

<块引用>

问题是在某些情况下(不是全部)我的 try/catch 块不会捕获它,而是作为未处理的异常停止执行。

正是预期会发生的事情。

请先 登录 后评论
Scott Dorman

最好的选择听起来像是将 Visual Studio 设置为在所有未处理的异常上中断(调试 -> 异常对话框,选中“公共语言运行时异常”框,可能还有其他选项)。然后在调试模式下运行你的程序。当 ANTLR 解析器代码抛出异常时,它应该被 Visual Studio 捕获并允许您查看它发生的位置、异常类型等。

根据描述,catch 块似乎是正确的,因此可能会发生以下几种情况之一:

  1. 解析器实际上并没有抛出异常
  2. 解析器最终会抛出并非源自 System.Exception 的东西
  3. 在另一个未处理的线程上引发了异常

听起来您可能已经排除了问题

请先 登录 后评论
  • 6 关注
  • 0 收藏,350 浏览
  • spoulson 提出于 2022-08-27 05:02