Why the form load can't catch exception?

2019-01-01 12:07发布

问题:

Is this a bug in Winforms? (tested on both VS2008 and VS2010)

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

I don\'t receive any error in that code, awhile ago, I\'m trying to formulate a solution for this question Parse a number from a string with non-digits in between

And I do this code in 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());        
}

I wonder why it didn\'t show the number. Then on moving the code to 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());        
}

...then I noticed that there\'s an error: Input string was not in a correct format.

Why Form1_Load didn\'t catch any exception, why it silently fail? The code just exit out of form1_load at string t = s.ToCharArray().TakeWhile...

回答1:

Rewrite, I\'ve since figured out where it comes from. Windows misbehaves when an exception is raised in a 32-bit process when it runs on a 64-bit version of Windows 7. It swallows any exception raised by code that runs in response to a Windows message that\'s triggered by the 64-bit windows manager. Like WM_SHOWWINDOW, the message that causes the Load event to get raised.

The debugger plays a role because when it is active, normal exception trapping in a Winforms app is turned off to allow the debugger to stop on an exception. That doesn\'t happen in this scenario because Windows 7 swallows the exception first, preventing the debugger from seeing it.

I\'ve written about this problem more extensively in this answer, along with possible workarounds.



回答2:

See this: The case of the disappearing OnLoad exception. It\'s by-design (though by-extremely-stupid-design, IMO). Your exception is hitting a kernel-mode boundary during the unwinding of the stack. If you can, switch to some other event, or don\'t let exceptions escape; this doesn\'t help if you\'re expecting your debugger to automatically break on an un-handled exception in OnLoad.

If you care, I wrote a bit more in this answer.



回答3:

The WinForms framework classes won\'t automatically catch any exceptions for you. That isn\'t a bug, it\'s by design - what would they do with the exception?

You have to have your own try/catch block in any event or alternatively handle the Application.ThreadException event. That event can be helpful for some generic handling code like logging the exception or displaying an error dialog, but obviously it can\'t do anything specific to any individual event or exception type.