2010-07-09 52 views
13

這是Winforms中的錯誤嗎?爲什麼表單加載無法捕捉異常?

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

我沒有收到任何錯誤代碼(在兩個VS2008和VS2010測試),前一段時間,我想制定這個問題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沒有發現任何異常,爲什麼它會默默地失敗?代碼剛剛退出form1_load string t = s.ToCharArray()。TakeWhile ...

+1

我已經在我的Win7 SP1 x64開發機器上成功地糾正了這種行爲。看[這個答案](http://stackoverflow.com/a/11997142/119527)如何。 – 2012-08-17 00:09:37

回答

21

重寫,我從那裏算出它來自哪裏。 Windows在64位版本的Windows 7上運行時,在32位進程中引發異常時,Windows會出現異常。它會吞噬由運行以響應由64位Windows管理器觸發的Windows消息而運行的代碼引發的任何異常。像WM_SHOWWINDOW一樣,會引發Load事件的消息。

調試器發揮作用,因爲當它處於活動狀態時,Winforms應用程序中的常規異常陷阱被關閉以允許調試器停止發生異常。在這種情況下不會發生這種情況,因爲Windows 7首先吞下異常,阻止調試器看到它​​。

我已經在this answer中更廣泛地寫過關於此問題以及可能的解決方法。

+0

似乎是一個錯誤。而在VS內部它默默地失敗,它沒有發現任何異常。如果獨立運行,它能夠捕獲異常 – Hao 2010-07-09 06:26:42

-1

WinForms框架類不會自動爲您捕捉任何異常。這不是一個錯誤,而是設計 - 他們會如何處理異常?

您必須在任何情況下都擁有自己的try/catch塊,或者處理Application.ThreadException事件。該事件對於一些通用的處理代碼很有幫助,例如記錄異常或顯示錯誤對話框,但顯然它不能執行任何特定於任何單個事件或異常類型的操作。

+0

嘗試執行我上面的代碼。對比**在Form1_Load中拋出新Exception(「Hey Yo!」)**的行爲,以及在button1_Click中拋出的行爲 – Hao 2010-07-09 04:27:44

5

看到這個:The case of the disappearing OnLoad exception。這是通過設計(儘管非常愚蠢的設計,國際海事組織)。在展開堆棧期間,您的異常正在觸發內核模式邊界。如果可以的話,切換到其他事件,或者不要讓例外逃脫;如果您希望調試程序在OnLoad中自動處理未處理的異常,這並沒有幫助。

如果你在意,我多寫一點in this answer