这令人非常恼火。现在我有一个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打破所有异常,我发现这种情况非常糟糕。它导致了很难在生产中调试的奇怪问题,因为这是一个内部工具,我真的想拥有它,以便在发生异常时实际上出错,而不是默默地忽略它。
有谁知道怎么做?
<小时/> 更新:只是为了更新我从评论中学到的东西。
这似乎是Windows的64位问题,正如我从this question学到的那样,我在发布之前没有看到。在那个问题中,它指出了Microsoft bug report关于这一点,有这样的说法:
您好,
此错误已关闭为“外部”,因为此行为是由x64版本的Windows处理异常引起的。当用户模式异常穿过内核转换时,x64版本的Windows不允许异常传播。因此,附加的调试器不知道发生异常导致调试器未能在未处理的异常中断。
遗憾的是,Visual Studo团队无法解决这个问题,这是操作系统设计的结果。有关此问题的所有反馈都应提交给Windows团队;但Windows团队认为这是“正确的”操作系统设计,并认为x86行为“不正确”。
最诚挚的问候, Visual Studio调试器
话虽如此,如果你的{{1}中有以下代码,那么构建不通过visual studio运行(或使用Ctrl + F5运行)似乎确实显示了JIT异常消息框 EXCEPT }}:
Program.cs
该代码将导致窗口忽略该异常。
但是,如果您(而不是)订阅Application.SetUnhandledExceptionMode(UnhandledExceptionMode.ThrowException);
事件,不仅会捕获您的异常,Visual Studio的调试器将中断未处理的异常!
答案 0 :(得分:16)
在Program.cs的主要功能中,您还应确保已打包调用以在try / catch中打开表单。另外,使用AppDomain.UnhandledException
来捕获异常。我们也添加了Application.ThreadException
。
我相信以下内容将为您提供可以抛出的所有异常的钩子......
static void Main()
{
try
{
System.Windows.Forms.Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
System.Windows.Forms.Application.ThreadException += new System.Threading.ThreadExceptionEventHandler(OnGuiUnhandedException);
AppDomain.CurrentDomain.UnhandledException += OnUnhandledException;
var form = new MainForm();
form.ShowDialog();
}
catch (Exception e)
{
HandleUnhandledException(e);
}
finally
{
// Do stuff
}
}
private static void HandleUnhandledException(Object o)
{
// TODO: Log it!
Exception e = o as Exception;
if (e != null)
{
}
}
private static void OnUnhandledException(Object sender, UnhandledExceptionEventArgs e)
{
HandleUnhandledException(e.ExceptionObject);
}
private static void OnGuiUnhandedException(object sender, System.Threading.ThreadExceptionEventArgs e)
{
HandleUnhandledException(e.Exception);
}
答案 1 :(得分:7)
请尝试以下操作。
这是代码段:
[STAThread]
public static void Main(string[] args)
{
try
{
Application.ThreadException += new ThreadExceptionEventHandler(Application_ThreadException);
//your program entry point
}
catch (Exception ex)
{
//manage also these exceptions
}
}
private void Application_ThreadException(object sender, ThreadExceptionEventArgs e)
{
ProcessException(e.Exception);
}
答案 2 :(得分:4)
一个简单的解决方法是不在调试器下运行。
由于某种原因,调试器正在屏蔽异常。如果您正常运行您的应用程序(Ctrl + F5),您将得到通常的“应用程序中发生未处理的异常...继续/退出?”对话框。
答案 3 :(得分:-1)
经常遇到这个并确定了有关64位操作系统和Form.Load事件的问题,我总是在Form.Shown事件中完成所有启动功能。出于所有实际目的,这是相同的事情(除了一些罕见的特殊情况),并且JIT消息在Shown事件中产生。