为什么表单加载无法捕获异常?

时间:2010-07-09 03:53:11

标签: winforms exception

这是Winforms中的错误吗? (在VS2008和VS2010上测试)

private void Form1_Load(object sender, EventArgs e)
{
    throw new Exception("Hey");            
}

我在该代码中没有收到任何错误,前一段时间,我正在尝试为此问题制定解决方案Parse a number from a string with non-digits in between

我在Form1_Load中执行此代码:

private void Form1_Load(object sender, EventArgs e)
{
    MessageBox.Show("X");
    string s = "12ACD";
    string t = s.ToCharArray().TakeWhile(c => char.IsDigit(c)).ToArray().ToString();
    MessageBox.Show("Y");
    int n = int.Parse(t);
    MessageBox.Show(n.ToString());        
}

我想知道为什么没有显示这个数字。然后将代码移动到button1_Click ...

private void button1_Click(object sender, EventArgs e)
{
    MessageBox.Show("X");
    string s = "12ACD";
    string t = s.ToCharArray().TakeWhile(c => char.IsDigit(c)).ToArray().ToString();
    MessageBox.Show("Y");
    int n = int.Parse(t);
    MessageBox.Show(n.ToString());        
}

...然后我注意到有一个错误:输入字符串的格式不正确。

为什么Form1_Load没有捕获任何异常,为什么它会无声地失败?代码只是从字符串t = s.ToCharArray()退出form1_load。TakeWhile ...

3 个答案:

答案 0 :(得分:21)

重写,我已经弄明白它的来源。 Windows在64位版本的Windows 7上运行时,如果在32位进程中引发异常,Windows会出现异常。它会吞下由响应由64位Windows管理器触发的Windows消息而运行的代码引发的任何异常。与WM_SHOWWINDOW一样,导致Load事件被引发的消息。

调试器起作用,因为当它处于活动状态时,Winforms应用程序中的正常异常捕获将被关闭,以允许调试器停止异常。在这种情况下不会发生这种情况,因为Windows 7首先吞下异常,阻止调试器看到它​​。

我在this answer中更广泛地介绍了这个问题,以及可能的解决方法。

答案 1 :(得分:5)

请参阅:The case of the disappearing OnLoad exception。它是按设计进行的(尽管极其愚蠢的设计,IMO)。您的异常是在展开堆栈期间遇到内核模式边界。如果可以,切换到其他一些事件,或者不要让异常逃脱;如果您期望调试器在OnLoad中自动中断未处理的异常,这无济于事。

如果你关心,我写了更多in this answer

答案 2 :(得分:-1)

WinForms框架类不会自动捕获任何异常。这不是一个错误,它是设计 - 他们会做什么与例外?

您必须在任何情况下拥有自己的try / catch块,或者处理Application.ThreadException事件。该事件对于某些通用处理代码(如记录异常或显示错误对话框)很有帮助,但显然它不能对任何单个事件或异常类型执行任何特定操作。