【问题标题】:Why is .NET exception not caught by try/catch block?为什么 .NET 异常没有被 try/catch 块捕获?
【发布时间】:2010-09-07 08:27:59
【问题描述】:

我正在开发一个使用 C# 的 ANTLR 解析器库的项目。我已经建立了一个语法来解析一些文本,并且效果很好。但是,当解析器遇到非法或意外标记时,它会抛出许多异常之一。问题是在某些情况下(不是全部)我的 try/catch 块不会捕获它,而是作为未处理的异常停止执行。

对我来说,问题是我无法在其他任何地方复制这个问题,只能在我的完整代码中。调用堆栈显示异常肯定发生在我的 try/catch(Exception) 块中。我唯一能想到的是,在我的代码和引发异常的代码之间发生了一些 ANTLR 程序集调用,并且这个库没有启用调试,所以我无法单步执行。我想知道不可调试的程序集是否会抑制异常冒泡?调用堆栈如下所示;外部程序集调用在 Antlr.Runtime 中:

Expl.Itinerary.dll!TimeDefLexer.mTokens() 第 1213 行 C# Antlr3.Runtime.dll!Antlr.Runtime.Lexer.NextToken() + 0xfc 字节 Antlr3.Runtime.dll!Antlr.Runtime.CommonTokenStream.FillBuffer() + 0x22c 字节 Antlr3.Runtime.dll!Antlr.Runtime.CommonTokenStream.LT(int k = 1) + 0x68 字节 Expl.Itinerary.dll!TimeDefParser.prog() 第 109 行 + 0x17 字节 C# Expl.Itinerary.dll!Expl.Itinerary.TDLParser.Parse(string Text = "", Expl.Itinerary.IItinerary Itinerary = {Expl.Itinerary.MemoryItinerary}) 第 17 行 + 0xa 字节 C#

Parse() 中最底层调用的代码 sn-p 如下所示:

     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);
     }

对我来说,一个 catch (Exception) 子句应该已经捕获了任何异常。有什么理由不这样做吗?

更新:我用 Reflector 追踪了外部组件,并没有发现任何螺纹迹象。该程序集似乎只是 ANTLR 生成代码的运行时实用程序类。抛出的异常来自 TimeDefLexer.mTokens() 方法,其类型为 NoViableAltException,它派生自 RecognitionException -> Exception。当词法分析器无法理解流中的下一个标记时,将引发此异常;换句话说,无效输入。应该会发生此异常,但它应该已被我的 try/catch 块捕获。

另外,ParserException 的重新抛出与这种情况无关。这是一个抽象层,它在解析期间接受任何异常并转换为我自己的 ParserException。我遇到的异常处理问题永远不会到达那行代码。事实上,我注释掉了“throw new ParserException”部分,仍然得到了相同的结果。

还有一件事,我修改了原来的 try/catch 块,改为捕获 NoViableAltException,消除了任何继承混淆。我仍然收到相同的结果。

有人曾经提出,有时 VS 在调试模式下捕获处理的异常时过于活跃,但这个问题也发生在发布模式下。

伙计,我还是很难过!我之前没有提到它,但我正在运行 VS 2008,我所有的代码都是 3.5。外部程序集为 2.0。此外,我的一些代码子类化了 2.0 程序集中的一个类。版本不匹配会导致此问题吗?

更新 2:我能够通过将 .NET 3.5 代码的相关部分移植到 .NET 2.0 项目并复制相同的场景来消除 .NET 版本冲突。在 .NET 2.0 中持续运行时,我能够复制相同的未处理异常。

我了解到 ANTLR 最近发布了 3.1。所以,我从 3.0.1 升级并重试。事实证明,生成的代码经过了一点重构,但在我的测试用例中出现了同样的未处理异常。

更新 3: 我在simplified VS 2008 project 中复制了这个场景。随意下载并亲自检查该项目。我已经采纳了所有很棒的建议,但还没有克服这个障碍。

如果您能找到解决方法,请分享您的发现。再次感谢!


谢谢,但是 VS 2008 会自动中断未处理的异常。另外,我没有 Debug->Exceptions 对话框。抛出的 NoViableAltException 完全是有意的,并且被设计为被用户代码捕获。由于未按预期捕获,因此程序执行会作为未处理的异常意外停止。

抛出的异常是从 Exception 派生的,并且 ANTLR 没有进行多线程。

【问题讨论】:

    标签: c# .net exception antlr


    【解决方案1】:

    我相信我理解这个问题。异常被捕获,问题在于调试器的行为混淆以及每个尝试重现它的人在调试器设置方面的差异。

    在您的 repro 的第三种情况下,我相信您会收到以下消息:“NoViableAltException 未被用户代码处理”和如下所示的调用堆栈:

    [外部代码] > TestAntlr-3.1.exe!TimeDefLexer.mTokens() 第 852 行 + 0xe 字节 C# [外部代码] TestAntlr-3.1.exe!TimeDefParser.prog() 第 141 行 + 0x14 字节 C# TestAntlr-3.1.exe!TestAntlr_3._1.Program.ParseTest(string Text = "foobar;") 第 49 行 + 0x9 字节 C# TestAntlr-3.1.exe!TestAntlr_3._1.Program.Main(string[] args = {string[0x00000000]}) 第 30 行 + 0xb 字节 C# [外部代码]

    如果您在调用堆栈窗口中右键单击并运行打开显示外部代码,您会看到:

    Antlr3.Runtime.dll!Antlr.Runtime.DFA.NoViableAlt(int s = 0x00000000, Antlr.Runtime.IIntStream 输入 = {Antlr.Runtime.ANTLRStringStream}) + 0x80 字节 Antlr3.Runtime.dll!Antlr.Runtime.DFA.Predict(Antlr.Runtime.IIntStream 输入 = {Antlr.Runtime.ANTLRStringStream}) + 0x21e 字节 > TestAntlr-3.1.exe!TimeDefLexer.mTokens() 第 852 行 + 0xe 字节 C# Antlr3.Runtime.dll!Antlr.Runtime.Lexer.NextToken() + 0xc4 字节 Antlr3.Runtime.dll!Antlr.Runtime.CommonTokenStream.FillBuffer() + 0x147 字节 Antlr3.Runtime.dll!Antlr.Runtime.CommonTokenStream.LT(int k = 0x00000001) + 0x2d 字节 TestAntlr-3.1.exe!TimeDefParser.prog() 第 141 行 + 0x14 字节 C# TestAntlr-3.1.exe!TestAntlr_3._1.Program.ParseTest(string Text = "foobar;") 第 49 行 + 0x9 字节 C# TestAntlr-3.1.exe!TestAntlr_3._1.Program.Main(string[] args = {string[0x00000000]}) 第 30 行 + 0xb 字节 C# [本机到托管转换] [管理到本地转换] mscorlib.dll!System.AppDomain.ExecuteAssembly(string assemblyFile, System.Security.Policy.Evidence assemblySecurity, string[] args) + 0x39 字节 Microsoft.VisualStudio.HostingProcess.Utilities.dll!Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly() + 0x2b 字节 mscorlib.dll!System.Threading.ThreadHelper.ThreadStart_Context(对象状态)+ 0x3b 字节 mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state) + 0x81 bytes mscorlib.dll!System.Threading.ThreadHelper.ThreadStart() + 0x40 字节

    调试器的消息告诉您,源自您的代码(来自 NoViableAlt)之外的异常正在通过您在 TestAntlr-3.1.exe!TimeDefLexer.mTokens() 中拥有的代码而未被处理。

    措辞令人困惑,但这并不意味着异常未被捕获。调试器让您知道您拥有的代码 mTokens()" 需要对通过它引发的异常保持稳健。

    对于那些没有重现问题的人来说,看看这看起来如何:

    • 转到工具/选项/调试和 关闭“仅启用我的代码 (仅限托管)”。或选项。
    • 转到调试器/异常并关闭“用户未处理” 通用语言运行时异常。

    【讨论】:

    • 我遇到了一个非常相似的问题——我为 Silverlight 构建的 ANTLR 词法分析器也是如此……在调试器中关闭“仅启用我的代码”解决了这个问题。调试器似乎在我的 catch 语句之前介入,如果您不知道发生了什么,看起来应用程序正在停止而没有捕获您的异常。我不完全理解为什么调试器会这样做,或者它如何区分“我的代码”和“我的库”等,但这就是修复。 (顺便说一句,我在 VS 2010 中没有看到“用户未处理”选项。
    • 禁用“仅启用我的代码”后,“用户未处理”选项将从调试器/异常中消失。唯一的选择是选中“Thrown”。
    【解决方案2】:

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

    我同意 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;
     }
    

    【讨论】:

      【解决方案3】:

      我可以告诉你这里发生了什么......

      Visual Studio 正在中断,因为它认为异常未处理。未处理是什么意思?好吧,在 Visual Studio 中,工具...选项...调试...常规...“仅启用我的代码(仅限托管)”中有一个设置。如果选中此项,并且如果异常从您的代码传播到与“不是您的代码”(例如,Antlr)的程序集中存在的方法调用关联的堆栈帧,则被认为是“未处理的”。出于这个原因,我关闭了 Enable Just My Code 功能。但是,如果你问我,这很蹩脚......假设你这样做:

      ExternalClassNotMyCode c = new ExternalClassNotMyCode();
      try {
          c.doSomething( () => { throw new Exception(); } );
      }
      catch ( Exception ex ) {}
      

      doSomething 在那里调用您的匿名函数并且该函数引发异常...

      请注意,如果启用“仅启用我的代码”,则根据 Visual Studio,这是一个“未处理的异常”。另外,请注意,它在调试模式下就像断点一样停止,但在非调试或生产环境中,代码完全有效并按预期工作。此外,如果您只是在调试器中“继续”,则应用程序会以愉快的方式继续运行(它不会停止线程)。它被认为是“未处理的”,因为异常通过不在您的代码中(即在外部库中)的堆栈帧传播。如果你问我,这很糟糕。请更改此默认行为 Microsoft。这是使用异常来控制程序逻辑的一个完全有效的案例。有时,您无法将第三方库更改为任何其他方式,这是完成许多任务的非常有用的方式。

      以 MyBatis 为例,您可以使用此技术停止处理通过调用 SqlMapper.QueryWithRowDelegate 收集的记录。

      【讨论】:

      • 如果您想建议改变 Visual Studio 的工作方式,我可以建议 Microsoft Connect 吗?
      • 我主要是想解释这个线程中缺少的行为。如果你问我,我对预期行为添加评论是完全可以接受的。
      • 我会对此进行辩论,但这不是我评论的重点。如果您对这个问题有强烈的感觉,我的评论是为了向您提出建议
      【解决方案4】:

      您使用的是 .Net 1.0 还是 1.1?如果是这样,那么 catch(Exception ex) 将不会从非托管代码中捕获异常。您需要改用 catch {}。详情请参阅这篇文章:

      http://www.netfxharmonics.com/2005/10/net-20-trycatch-and-trycatchexception/

      【讨论】:

      【解决方案5】:

      我和@Shaun Austin 在一起 - 尝试使用完全限定名称包装 try

      catch (System.Exception)
      

      看看是否有帮助。ANTLR 文档是否说明应该抛出什么异常?

      【讨论】:

        【解决方案6】:

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

        【讨论】:

          【解决方案7】:

          对我来说,一个 catch (Exception) 子句应该已经捕获了任何异常。有什么理由不这样做吗?

          我能想到的唯一可能是其他东西在您之前捕获它并以似乎是未捕获异常的方式处理它(例如退出进程)。

          我的 try/catch 块不会捕获它,而是作为未处理的异常停止执行。

          您需要找出导致退出过程的原因。它可能不是未处理的异常。 您可以尝试使用在“{,,kernel32.dll}ExitProcess”上设置断点的本机调试器。然后使用SOS 来判断哪个托管代码正在调用退出进程。

          【讨论】:

            【解决方案8】:

            我个人完全不相信线程理论。

            有一次我以前见过这个,我正在使用一个库,它也定义了异常和使用我的意思是实际的 Catch 指的是不同的“异常”类型(如果它已经完全限定了它是 Company.Lib.Exception 但不是因为使用)所以当它捕获一个被抛出的正常异常时(如果我没记错的话是某种参数异常)它只是不会捕获它,因为类型没有不匹配。

            因此,总而言之,在该类的 using 中的不同命名空间中是否还有另一个 Exception 类型?

            编辑:检查这一点的快速方法是确保在您的 catch 子句中您将异常类型完全限定为“System.Exception”并试一试!

            EDIT2:好的,我已经尝试了代码并暂时承认失败。如果没有人提出解决方案,我将不得不在早上再看看它。

            【讨论】:

              【解决方案9】:

              嗯,我不明白这个问题。我下载并尝试了您的示例解决方案文件。

              在 TimeDefLexer.cs 的第 852 行中引发了一个异常,该异常随后由 Program.cs 中的 catch 块处理,该块只是说 已处理的异常

              如果我取消注释上面的 catch 块,它将进入该块。

              这里似乎有什么问题?

              正如 Kibbee 所说,Visual Studio 会在出现异常时停止,但如果您要求它继续,异常会被您的代码捕获。

              【讨论】:

                【解决方案10】:

                我下载了示例 VS2008 项目,在这里也有点难过。但是,我能够克服异常,尽管可能不会以一种对您有用的方式。但这是我发现的:

                mailing list post 讨论了您遇到的问题。

                从那里,我在主 program.cs 文件中添加了几个虚拟类:

                class MyNoViableAltException : Exception
                {
                    public MyNoViableAltException()
                    {
                    }
                    public MyNoViableAltException(string grammarDecisionDescription, int decisionNumber, int stateNumber, Antlr.Runtime.IIntStream input)
                    {
                    }
                }
                class MyEarlyExitException : Exception
                {
                    public MyEarlyExitException()
                    {
                    }
                
                    public MyEarlyExitException(int decisionNumber, Antlr.Runtime.IIntStream input)
                    {
                    }
                }
                

                然后在 TimeDefParser.cs 和 TimeDefLexer.cs 中添加 using 行:

                using NoViableAltException = MyNoViableAltException;
                using EarlyExitException = NoViableAltException; 
                

                这样,异常会冒泡到假异常类中并且可以在那里处理,但在 TimeDefLexer.cs 中的 mTokens 方法中仍然会抛出异常。将其包装在该类中的 try catch 中会捕获异常:

                            try
                            {
                                alt4 = dfa4.Predict(input);
                            }
                            catch
                            {
                            }
                

                我真的不明白为什么将它包装在内部方法中,而不是从处理错误的地方调用它,如果线程不在播放中,但无论如何希望这将指向比我更聪明的人在正确的方向.

                【讨论】:

                  【解决方案11】:

                  我下载了您的代码,一切正常。

                  Visual Studio 调试器正确拦截所有异常。捕获块按预期工作。

                  我正在运行 Windows 2003 server SP2、VS2008 Team Suite (9.0.30729.1 SP)

                  我尝试为 .NET 2.0、3.0 和 3.5 编译您的项目

                  @Steve Steiner,您提到的调试器选项与此行为无关。

                  我尝试在没有可见效果的情况下使用这些选项 - catch 块设法拦截所有异常。

                  【讨论】:

                    【解决方案12】:

                    Steve Steiner 是正确的,异常源自 antlr 库,通过 mTokens() 方法并被 antlr 库捕获。问题是这个方法是由 antlr 自动生成的。因此,当您生成解析器/词法分析器类时,处理 mTokens() 中的异常的任何更改都将被覆盖。

                    默认情况下,antlr 会记录错误并尝试恢复解析。您可以覆盖它,以便 parser.prog() 在遇到错误时抛出异常。从您的示例代码中,我认为这是您所期望的行为。

                    将此代码添加到您的语法 (.g) 文件中。您还需要在调试菜单中关闭“仅启用我的代码”。

                    @members {
                    
                        public override Object RecoverFromMismatchedSet(IIntStream input,RecognitionException e,    BitSet follow)  
                        {
                            throw e;
                        }
                    }
                    
                    @rulecatch {
                        catch (RecognitionException e) 
                        {
                            throw e;
                        }
                    }
                    

                    这是我对“Definitive ANTLR Reference”一书的“Exiting the recogniser on first error”一章中给出的示例的 C# 版本的尝试。

                    希望这就是您想要的。

                    【讨论】:

                      【解决方案13】:

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

                      【讨论】:

                        【解决方案14】:

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

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

                        1. 解析器实际上并未抛出异常
                        2. 解析器最终会抛出一些不是从 System.Exception 派生的东西
                        3. 在另一个未被处理的线程上引发了异常

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

                        【讨论】:

                          【解决方案15】:

                          我用 Reflector 追踪了外部组件,没有发现任何螺纹痕迹。

                          找不到线程不代表没有线程

                          .NET 有一个“线程池”,它是一组“备用”线程,大部分时间处于空闲状态。某些方法会导致事情在其中一个线程池线程中运行,因此它们不会阻塞您的主应用程序。

                          明显的例子是像ThreadPool.QueueUserWorkItem这样的东西,但是还有很多其他的东西也可以在线程池中运行看起来不那么明显的东西,比如Delegate.BeginInvoke

                          真的,你需要do what kibbee suggests

                          【讨论】:

                            【解决方案16】:

                            您是否尝试在 catch 子句中打印 (Console.WriteLine()) 异常,而不是使用 Visual Studio 并在控制台上运行您的应用程序?

                            【讨论】:

                              【解决方案17】:

                              我相信史蒂夫·施泰纳是正确的。在研究 Steve 的建议时,我遇到了 this thread 在工具|选项|调试器|常规中谈论“启用我的代码”选项。建议调试器在非用户代码抛出或处理异常时在某些情况下中断。我不确定为什么这甚至很重要,或者为什么调试器会明确表示异常实际上是未处理的。

                              我可以通过禁用“仅启用我的代码”选项来消除错误中断。这也通过删除“用户处理”列来更改调试|异常对话框,因为它不再适用。或者,您可以取消选中 CLR 的“用户处理”框并获得相同的结果。

                              感谢大家的帮助!

                              【讨论】:

                                【解决方案18】:

                                您可以将 VS.Net 设置为在发生任何异常时立即中断。只需在调试模式下运行您的项目,一旦抛出异常,它将立即停止。那么您应该更好地了解为什么它没有被捕获。

                                此外,您可以添加一些代码来捕获所有未处理的异常。

                                Application.ThreadException += new ThreadExceptionEventHandler(ThreadExceptionHandler);
                                
                                 // Catch all unhandled exceptions in all threads.
                                 AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(UnhandledExceptionHandler);
                                

                                【讨论】:

                                  【解决方案19】:

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

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

                                  AppDomain.CurrentDomain.UnhandledException 
                                  

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

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

                                  【讨论】:

                                    【解决方案20】:

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

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

                                    正是预期会发生的事情。

                                    【讨论】:

                                      【解决方案21】:

                                      我同意Daniel Augerkronoz 的观点,这听起来像是一个与线程有关的异常。除此之外,还有我的其他问题:

                                      1. 完整的错误消息说明了什么?这是什么异常?
                                      2. 根据您在此处提供的堆栈跟踪,您在 TimeDefLexer.mTokens() 中的代码是否引发了异常?

                                      【讨论】:

                                        【解决方案22】:

                                        我不确定我是否不清楚,但如果是这样,我看到调试器停止执行并出现 NoViableAltException 类型的“未处理异常”。最初,我对这个 Debug->Exceptions 菜单项一无所知,因为 MS 希望您在 VS 安装时,在您不知道它们有何不同时提交配置文件。显然,I was not on the C# dev profile and was missing this option。在最终调试所有抛出的 CLR 异常之后,不幸的是,我无法发现任何导致此未处理异常问题的原因的新行为。所有抛出的异常都是预期的,并且应该在 try/catch 块中处理。

                                        我查看了外部程序集,没有多线程的证据。我的意思是不存在对 System.Threading 的引用,也没有使用任何委托。我熟悉构成实例化线程的方式。我通过在出现未处理异常时观察线程工具箱来验证这一点,以查看只有一个正在运行的线程。

                                        我与 ANTLR 人员有一个未解决的问题,所以也许他们之前已经能够解决这个问题。我已经能够在 VS 2008 和 VS 2005 下使用 .NET 2.0 和 3.5 在一个简单的控制台应用程序项目中复制它。

                                        这只是一个痛点,因为它迫使我的代码只能使用已知的有效解析器输入。如果使用IsValid() 方法会根据用户输入抛出未处理的异常,那么它是有风险的。当更多地了解这个问题时,我会及时更新这个问题。

                                        【讨论】:

                                          【解决方案23】:

                                          @spoulson,

                                          如果你能复制它,你能把它贴在某个地方吗?您可以尝试的一种方法是使用带有 SOS 扩展的 WinDBG 来运行应用程序并捕获未处理的异常。它将在第一次机会异常时中断(在运行时尝试查找处理程序之前),您可以在那时看到它来自哪里,以及哪个线程。

                                          如果您以前没有使用过 WinDBG,可能会有点不知所措,但这里有一个很好的教程:

                                          http://blogs.msdn.com/johan/archive/2007/11/13/getting-started-with-windbg-part-i.aspx

                                          启动 WinDBG 后,您可以通过转到 Debug->Event Filters 来切换未处理异常的中断。

                                          【讨论】:

                                            【解决方案24】:

                                            哇,到目前为止,在报告中,有 2 份工作正常,1 份遇到了我报告的问题。有哪些版本的 Windows、使用的 Visual Studio 和带有内部版本号的 .NET 框架?

                                            我正在运行 XP SP2、VS 2008 Team Suite (9.0.30729.1 SP)、C# 2008 (91899-270-92311015-60837) 和 .NET 3.5 SP1。

                                            【讨论】:

                                              【解决方案25】:

                                              如果您在项目中使用 com 对象并尝试捕获块而不捕获异常,则当异常跨越 AppDomain 或托管/本机边界(仅限托管)选项时,您将需要禁用工具/调试/中断。

                                              【讨论】:

                                                猜你喜欢
                                                • 1970-01-01
                                                • 2019-07-12
                                                • 1970-01-01
                                                • 1970-01-01
                                                • 2021-05-13
                                                • 1970-01-01
                                                • 2012-02-24
                                                • 1970-01-01
                                                • 1970-01-01
                                                相关资源
                                                最近更新 更多