这变得非常令人恼火。现在我有一个 winforms 应用程序,事情运行不正常,但据我所知,没有抛出任何异常。在单步执行几乎所有相关代码后,结果发现在我的应用程序启动时抛出了异常。
长话短说,在 WinForms 中,虽然它本身很棒,但如果发生异常,WinForms 库会忽略它。不会抛出“发生未处理的异常”JIT 消息,它只是停止处理当前事件并返回到 GUI。
这会导致随机错误,因为由于加载数据之前发生异常,因此未调用加载数据的代码。
为了查看其实际效果,我创建了一个全新的 WinForms 应用程序,并输入了以下代码:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
string blah = null;
blah.Trim();
}
}
按 F5 即可加载表单,即使抛出空引用,也不会显示任何错误。
然后我尝试去我的Program.cs
主要方法并添加Application.SetUnhandledExceptionMode(UnhandledExceptionMode.ThrowException);
到它。我的表单仍然加载,没有引发任何错误。
尽管我知道我可以告诉 VS 在所有异常上中断,但我发现这种情况非常糟糕。它会导致非常奇怪的问题,在生产中很难调试,而且由于这是一个内部工具,我真的很想拥有它,因此当异常发生时它实际上会出错,而不是默默地忽略它。
有谁知道如何做到这一点?
Update: Just to update on things I have learned from the comments.
据我了解,这似乎是 Windows 的 64 位问题这个问题 https://stackoverflow.com/questions/4933958/vs2010-does-not-show-unhandled-exception-message-in-a-64-bit-winforms-application我在发布之前没有看到。在那个问题中它指出了一个微软错误报告 https://connect.microsoft.com/VisualStudio/feedback/details/357311/silent-exceptions-on-x64-development-machines关于这一点,其中有这样一句话:
Hello,
此错误已作为“外部”关闭,因为此行为是由 x64 版本的 Windows 处理异常的方式导致的。当用户模式异常跨越内核转换时,x64 版本的 Windows 不允许异常传播。因此,附加的调试器不知道发生了异常,导致调试器无法在未处理的异常上中断。
不幸的是,Visual Studo 团队无法解决这个问题,这是操作系统设计的结果。有关此问题的所有反馈均应发送给 Windows 团队;然而,Windows 团队认为这是“正确的”操作系统设计,并认为 x86 行为是“不正确的”。
此致,
Visual Studio 调试器
话虽如此,未通过 Visual Studio 运行的构建(或使用 Ctrl+F5 运行)似乎确实显示了 JIT 异常消息框EXCEPT如果你的程序中有以下代码Program.cs
:
Application.SetUnhandledExceptionMode(UnhandledExceptionMode.ThrowException);
该代码将导致 Windows 忽略该异常。
但是,如果您(相反)订阅了Application.ThreadException
事件,不仅会捕获你的异常,Visual Studio 的调试器will中断未处理的异常!