我有一个有趣的问题,就是在应用程序关闭期间,栈中似乎忽略了try/catch块。
由于时间紧迫,我还没有一个可行的测试项目(否则我肯定会试图重现这个问题),但请考虑以下代码片段。
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”抛出异常,即使当前对“RunAndPossiblyThrow”的所有使用中,“doThrow”都为false。我甚至已经修改了代码,看起来像“RunAndIgnoreThrow”,但是在UI关闭后仍然会崩溃。
Eric Lippert先生,我每天都读你的博客,我真希望听到它是某个已知的bug,而我没有疯掉。
编辑: 这是多线程的,并且我已经验证了所有对象在被访问时都没有被修改。
编辑: 明确显示异常是我们自己的。
编辑: 忘了提到,这是在关闭时,不幸的是,Visual Studio无法直接捕获崩溃。它可能在除UI线程以外的线程上崩溃,一旦主线程关闭,就会关闭。我只能通过反复运行和关闭应用程序,打开任务管理器,“创建转储文件”并查看Windbg中产生的超过400MB混乱结果来调试。 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不再阻止异常。
编辑和最终版 显然,转储文件列出了最近的一次first-chance异常。我通过创建一个在try catch中抛出并睡眠10秒的新项目进行了验证。在等待期间,我得到了.dmp文件,确实发现我的完全捕获的异常正在显示。
我会给有用的答案打分,但不幸的是,我的代码仍然没有任何原因或逻辑崩溃...