Winforms 为什么表单加载可以';不捕捉异常?

Winforms 为什么表单加载可以';不捕捉异常?,winforms,exception,Winforms,Exception,这是Winforms中的错误吗?(在VS2008和VS2010上测试) 我没有收到任何错误的代码,一段时间前,我正试图制定一个解决这个问题的方案 我在Form1_Load中执行以下代码: private void Form1_Load(object sender, EventArgs e) { MessageBox.Show("X"); string s = "12ACD"; string t = s.ToCharArray().TakeWhile(c => cha

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

我没有收到任何错误的代码,一段时间前,我正试图制定一个解决这个问题的方案

我在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());        
}
我想知道为什么它没有显示号码。然后在将代码移动到按钮1时,单击

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\u加载没有捕获任何异常,为什么它会自动失败?代码仅在字符串t=s.ToCharArray()处退出form1\u load。TakeWhile…

WinForms framework类不会自动捕获任何异常。这不是一个bug,这是出于设计——如果出现异常,他们会怎么做


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

重写,我已经找到了它的来源。当在64位版本的Windows 7上运行的32位进程中引发异常时,Windows会出现错误行为。它接受由响应由64位Windows管理器触发的Windows消息而运行的代码引发的任何异常。与WM_SHOWWINDOW一样,引发加载事件的消息

调试器之所以发挥作用,是因为当它处于活动状态时,Winforms应用程序中的正常异常捕获将被关闭,以允许调试器在出现异常时停止。在这种情况下不会发生这种情况,因为Windows7首先会吞并异常,从而阻止调试器看到它

我在中更详细地介绍了这个问题,以及可能的解决方法。

请参阅:。这是出于设计(尽管在我看来,这是非常愚蠢的设计)。您的异常是在堆栈展开期间碰到内核模式边界。如果可以,切换到其他事件,或者不要让异常逃逸;如果您希望调试器在OnLoad中遇到未处理的异常时自动中断,那么这将没有帮助


如果你介意的话,我还写了一点。

试着执行上面的代码。对比Form1\u Load中抛出新异常(“Hey Yo!”)的行为和button1\u Click中抛出新异常的行为似乎是一个错误。当inside VS以静默方式失败时,它不会捕获任何异常。如果独立运行,它能够捕获异常。我已经在我的Win7 SP1 x64开发机器上成功更正了此行为。看看怎么做。
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());        
}