我有一个在 Visual Studio 下运行良好的应用程序。
但是,当我单独运行它时,不会处理某个引发异常的操作。(预计会出现异常,但在 VS 下已正确处理。)
我在 machine.config 中添加了一行以启用 JIT 调试,以尝试定位问题,但我无法重新创建错误(异常处理正确)。删除该行会导致错误再次出现。
我应该如何开始寻找原因?
我的代码的相关部分(我相信)(经过编辑以删除无关的细节)位于http://pastebin.com/i2zLCTn5。
我有一个在 Visual Studio 下运行良好的应用程序。
但是,当我单独运行它时,不会处理某个引发异常的操作。(预计会出现异常,但在 VS 下已正确处理。)
我在 machine.config 中添加了一行以启用 JIT 调试,以尝试定位问题,但我无法重新创建错误(异常处理正确)。删除该行会导致错误再次出现。
我应该如何开始寻找原因?
我的代码的相关部分(我相信)(经过编辑以删除无关的细节)位于http://pastebin.com/i2zLCTn5。
一些可能会影响您的代码在不同 Visual Studio 环境中的行为的建议:
关闭“托管进程”... http://msdn.microsoft.com/en-us/library/ms185330(v=vs.80).aspx
运行程序,然后“附加到进程”(它不会在托管进程中,并且模块将被加载并 JIT 优化)。
在 Exceptions 对话框中,勾选正在被吃掉/处理的 Exception 的“Thrown”复选框......这样您就可以追踪谁在处理它以及为什么。如果在那里处理异常,您将需要安装 NET Framework 源代码,以便您可以查看详细信息。
您可以尝试在 WinDBG 下运行它(它的行为可能会有所不同,因为您不会在托管进程下运行,即 .vshost)....确保您有扩展 DLL PSSCOR4(如果使用 .NET 4 ) 以便您能够理解事物。
所以,我发现了——或者更确切地说,一位朋友解释了——这个问题的原因:
当 JIT 调试被禁用时,您无法跨线程捕获异常,即使执行看起来正常。
在 Form.Closing 事件处理程序中引发了异常:
form.Closing += new delegate
{
switch(form.DialogResult)
{
case DialogResult.OK:
// do stuff;
break;
case DialogResult.Cancel:
throw new AbortOperationException();
}
}
// ...
try
{
mainForm.Invoke(new Function<Form, DialogResult>(form.ShowDialog), mainWindow);
}
catch (AbortOperationException)
{
// handle abort
}
解决方案是稍微重构以消除throw
:
form.Closing += new delegate
{
if (form.DialogResult == DialogResult.OK)
{
// do stuff
}
}
// ...
var result = (DialogResult)mainForm.Invoke(new Function<Form, DialogResult>
if (result == DialogResult.Cancel)
{
// handle abort
}