【问题标题】:Why would this catch all block not in fact catch all为什么这个捕获所有块实际上不能捕获所有
【发布时间】:2009-05-22 16:22:09
【问题描述】:

代码相当简单 --- 问题是 groupPath 字符串中有一个无效字符(准确地说是“/”)。

我正在尝试做的(至少作为权宜之计)是跳过我无法获得 cn 的 DirectoryEntries --- 不管为什么。

但是,当我运行此代码时,catch 块没有运行,而是得到: 服务器无法运行。和未处理的 System.Runtime.InteropServices.COMException。

为什么catch块不能捕捉到这个异常。

try
{
    using (DirectoryEntry groupBinding = new DirectoryEntry("LDAP://" + groupPath))
    {
        using (DirectorySearcher groupSearch = new DirectorySearcher(groupBinding))
        {

            using (DirectoryEntry groupEntry = groupSearch.FindOne().GetDirectoryEntry())
            {
                results.Add(string.Format("{0}", groupEntry.Properties["cn"].Value.ToString()));
            }
        }
    }
}
catch
{
    Logger.Error("User has bad roles");
}

补充意见: 代码实际上是在一个自定义 RoleProvider 中,奇怪的是,如果我在一个简单的 winforms 应用程序中引用这个提供程序,并使用相同的输入调用这个相同的方法,catch 块就会完全按照它的预期做。我认为这表明关于 .NET 异常与 COM 异常的建议答案并不准确。 虽然我不明白为什么这段代码在从 WebDev 服务器执行时无法捕获

【问题讨论】:

  • 在调试器中,还是在构建中?
  • 您在哪一行得到异常?什么线程?
  • 另外,你能添加例外吗? (Exception.ToString())
  • 我想知道是否可能在包含 Using 语句产生的 Dispose 的隐式 finally 块之一中引发了异常?在 finally 块中没有一些奇怪的异常处理规则吗?无论如何,如果发生这种情况,我会拉出 Using 语句并对其进行长期编码,以便更好地处理异常发生的确切位置。
  • 你不是在发布模式下调试,是吗?否则可能会发生这种奇怪的事情。

标签: c# .net directoryservices roleprovider


【解决方案1】:

当您不指定要捕获的内容时,它默认为 .NET 异常。您的异常在 COM 中,其中 .NET 未设置为捕获异常。处理这个问题的最好方法是捕获 COM 异常,它应该看起来像这样:

    try
    {

    }
    catch (System.Runtime.InteropServices.COMException COMex)
    {

    }
    catch (System.Exception ex)
    {

    }

【讨论】:

  • COMException 继承 ExternalException 继承 SystemException 继承 Exception。除非有我遗漏的东西,否则这不应该是错过 catch 的情况,也许只是添加他 System.Exception catch?
  • COMException 可能继承自 System.Exception,但它仍然没有在与 System.Exception 的 COM 互操作中被捕获。我已经与 AutoCAD 进行了很多互操作,这让我发疯了很长一段时间,因为我习惯于使用 catch all 而不是指定我的确切异常。
  • 哇,拿着电话——你是认真的吗!?显然你是,但这真的很令人惊讶而且很糟糕!任何其他 ExternalException 类型都会发生这种情况吗?
  • 我只是在 AutoCAD 中真正使用过它,而且我不得不使用 Autodesk.AutoCAD.Runtime.Exception 相当多,这源自 System.Exception。我花了几天时间试图弄清楚为什么我的捕获导致 AutoCAD 崩溃,当时我认为我正在正确处理异常。
  • Noah,如果他使用了 catch (Exception ex) {...},根据您的经验,它会捕获 COMException 吗? ie 是不是只有在你没有指定任何异常类型时才会发生奇怪的事情,或者除非你完全指定 COMException,否则它总是会发生?
【解决方案2】:

有三个原因:

  1. 运行时存在错误
  2. 应用程序和/或线程作为某些执行代码的一部分而结束
  3. 你没有看到全貌

我个人投了 3 票,并且我参加过无数次调试会议,我想知道为什么有些代码没有处理我的异常,而实际上是 Visual Studio 被配置为在所有抛出的异常上停止,而不管不管他们是否被抓到。

您是否尝试过仅要求程序继续在调试器中运行,然后查看它是否会在 catch-block 中结束?

另外,检查 Visual Studio 中的设置,转到“调试”->“异常”对话框,并检查是否选中了任何“抛出”复选框。如果你有,那可能是你的问题。

当然,如果你在运行时看到这个问题,没有附加调试器,那我就不知道了,除了上面的第1点和第2点。

当然还有第 4 点:未知数。

【讨论】:

    【解决方案3】:

    从该 try 块中抛出的 COMException 将被 catch 块捕获并吞下。

    休息一下,给自己喝杯咖啡,在“Logger.Error...”行设置断点,然后重试。

    【讨论】:

      【解决方案4】:

      除了 COMException 之外,还有一些不要被捕获的异步异常,例如:

      • OutOfMemoryException
      • StackoverflowException(不,这不是与本网站有关的笑话 :))
      • ThreadAbortException

      你确定不是这样吗?

      【讨论】:

      • 仅供参考,您可以捕获 OutOfMemoryException。到时候能否成功释放一些内存(释放对事物的引用)取决于你的应用程序。
      • 嗯,是的,从技术上讲,您可以捕获它们,但是一旦您退出 catch 块,它们就会被 CLR 运行时重新抛出......
      【解决方案5】:

      我遇到了类似的问题。我正在调用引发错误的 VB6 COM 对象。实际的异常类型原来是 System.Reflection.TargetInvocationException。 innerException 被设置为 COMException。我最终捕获了 System.Reflection.TargetInvocationException 并检查了 innerException

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-01-25
        • 1970-01-01
        • 2023-04-08
        • 1970-01-01
        • 1970-01-01
        • 2015-06-13
        相关资源
        最近更新 更多