【发布时间】: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# 的内部。
-
发布堆栈跟踪是必要的。