【问题标题】:When is a try catch not a try catch?什么时候尝试捕获不是尝试捕获?
【发布时间】:2010-04-19 01:16:39
【问题描述】:

我有一个有趣的问题,在应用程序关闭期间,堆栈中似乎忽略了 try / catch 块。

我没有一个有效的测试项目(由于截止日期,否则我会完全尝试重现这个),但请考虑以下代码 sn-p。

class IndexNotFoundException : Exception { }

public static string RunAndPossiblyThrow(int index, bool doThrow)
{
    try
    {
        return Run(index);
    }
    catch(IndexNotFoundException e)
    {
         if(doThrow)
             throw;
    }
    return "";
}

public static string Run(int index)
{
    if(_store.Contains(index))
        return _store[index];
    throw new IndexNotFoundException ();
}

public static string RunAndIgnoreThrow(int index)
{
    try
    {
        return Run(index);
    }
    catch(IndexNotFoundException e)
    {
    }
    return "";
}

在运行时,这种模式非常有效。我们获得了对依赖于程序控制异常的代码的旧版支持(不好),我们可以继续前进并慢慢删除用于程序控制的异常。

但是,当关闭我们的 UI 时,我们会看到从“Run”抛出的异常,即使“doThrow”对于“RunAndPossiblyThrow”的所有当前使用都是错误的。我什至通过将代码修改为“RunAndIgnoreThrow”来验证这一点,但在 UI 关闭后我仍然会崩溃。

先生。 Eric Lippert,我每天都阅读你的博客,我很想知道这是一些已知的错误,我不会发疯的。

编辑 这是多线程的,我已经验证了所有对象在被访问时都没有被修改

编辑 明确显示异常是我们的

编辑 忘了提,这是关闭,不幸的是视觉工作室无法直接捕捉到崩溃。它很可能在 UI 线程以外的线程上崩溃,一旦主线程关闭,它就会关闭。我只能通过重复运行和关闭应用程序来调试它,打开任务管理器,“创建转储文件”并查看 Windbg 中产生的 400+mb 混乱。 Win7 64位供参考。确保这对您有意义。

编辑

以下代码在关机时仍然显示相同的异常。

class IndexNotFoundException : Exception { }

public static string RunAndPossiblyThrow(int index, bool doThrow)
{
    try
    {
        return Run(index);
    }
    catch
    {
    }
    return "";
}

public static string Run(int index)
{
    if(_store.Contains(index))
        return _store[index];
    throw new IndexNotFoundException ();
}

似乎唯一摆脱异常的就是直接去

class IndexNotFoundException : Exception { }

public static string RunAndPossiblyThrow(int index, bool doThrow)
{
    try
    {
        return Run(index);
    }
    catch
    {
    }
    return "";
}

public static string Run(int index)
{
    if(_store.Contains(index))
        return _store[index];
    return "";
}

例外自然没有了,但我对发疯的恐惧仍然存在。

编辑

它变得更糟了......这仍然崩溃......

class IndexNotFoundException : Exception { }

public static string RunAndPossiblyThrow(int index, bool doThrow)
{
    try
    {
        throw new IndexNotFoundException();
    }
    catch
    {
    }
    return "";
}

编辑 我有一种明显的感觉,这会让我一事无成。除了奇怪的行为之外,我还可以注意到在上述情况下执行 UI 期间,try catch 正在忠实地执行。我的 UI 没有崩溃,并且充满了空字符串。但是,一旦我开始关闭 UI,崩溃就会出现,并且 try catch 不再阻止异常。

编辑 & 最终 显然,转储文件中列出了最近的第一次机会异常。我通过创建一个新项目来验证这一点,该项目投入了 try catch 并睡了 10 秒。在等待期间,我得到了 .dmp 文件,果然,我完全捕获的异常出现了。

我会为有用的答案标记一些要点,但不幸的是,我的代码崩溃的原因仍然没有韵律或原因......

【问题讨论】:

  • 你能发布异常信息吗?堆栈跟踪、异常类型、消息等?
  • 该异常是我们在项目中创建的 plane-jane IndexNotFound 异常。托管代码没有抛出任何东西,这是我们的异常和问题中描述的堆栈。我会更新问题。
  • 这个“崩溃”实际上是异常消息,带有堆栈跟踪,还是 Windows 崩溃对话框?
  • 这是一个 Windows 崩溃对话框。尊重事件日志中的 APPCRASH 事件,列出我们的错误应用程序名称和“RPCRT4.dll”错误模块名称。我可以向你保证,我们不会直接使用这个 dll,我假设它来自 C# 的内部。
  • 发布堆栈跟踪是必要的。

标签: c# exception


【解决方案1】:

添加一个异常作为额外的捕获。我认为您遇到了除 ApplicationException 之外的其他异常,那就是导致您的应用程序崩溃的异常。

【讨论】:

  • 我之前说过,我希望其他异常是异常&崩溃。这是我们正在寻找和失踪的例外。
  • 好吧,还有其他例外情况——它们正在使您的应用程序崩溃。
  • 在生成的 .dmp 文件中,唯一包含的例外是我的例外。我不确定我能清楚多少。
  • 当你使用catch{ }时你能做到这一点吗(即没有异常类型的catch)?
  • 为了不遗余力,我尝试了那个 jake,仍然抛出异常。如果我鲁莽了,对不起 Otavio。
【解决方案2】:

有各种无法捕获的异常。特别是堆栈溢出!其中一个可能发生在您的代码中的某个地方吗?

见http://www.bluebytesoftware.com/blog/PermaLink,guid,223970c3-e1cc-4b09-9d61-99e8c5fae470.aspx

【讨论】:

  • 这是一个很好的资源。不幸的是,我相对确定这些异常中的每一个仍然可以在调试器中捕获。不幸的是,没有多少调试器能让我捕捉到任何崩溃的东西。这看起来像一个不错的博客,内容量很大,如果更新不超过每月 1 次。我会把它添加到列表中。谢谢,
【解决方案3】:

您是否尝试过添加“finally”子句?只是为了看看它是否不会完全忽略try/catch?理论上,无论如何它都应该在退出 try/catch 之前跳转到该行。

如果它仍然忽略这一点,那么它肯定有一些奇怪的地方。

【讨论】:

    【解决方案4】:

    可能您从 Run 中捕获并再次抛出一些其他异常。可能 _store 是 null 什么的。

    【讨论】:

      【解决方案5】:

      一些可能有助于诊断的事情:

      • 注册 AppDomain.CurrentDomain.UnhandledException 以便您可以查看是否在 UI 线程以外的线程上发生了崩溃

      • 注册 Application.ThreadException 以捕获 UI 线程中未捕获的任何异常

      • 由于这是在关闭期间发生的,您是否使用了任何可能在终结器线程上抛出的终结器?

      【讨论】:

      • 两个处理程序都已注册,并且都没有被命中。否则,这将只是解析我们的日志的简单问题。在我将这些处理程序添加到代码中的那一天,生活变得轻松多了。据我所知,我们没有在代码中明确声明任何终结器。我们相当依赖 IDispose 来在我们完成后删除它们。
      • 您可能会检查那些在应用程序关闭之后仍然存在的线程,但如果 AppDomain 在所有线程终止之前释放其 UnhandledException 处理程序,我会感到惊讶。
      猜你喜欢
      • 2020-07-31
      • 2019-08-25
      • 2017-09-12
      • 1970-01-01
      • 1970-01-01
      • 2010-09-12
      • 2017-09-05
      • 1970-01-01
      • 2011-08-23
      相关资源
      最近更新 更多