2010-04-27 39 views
6

考慮以下簡單的應用程序:在主捕捉異常()方法

public static void Main() 
{ 
    Application.EnableVisualStyles(); 
    Application.SetCompatibleTextRenderingDefault(false); 

    try 
    { 
     Application.Run(new Form1()); 
    } 
    catch (Exception ex) 
    { 
     MessageBox.Show("An unexpected exception was caught."); 
    } 

} 

Form1.cs中包含:通過在VS一個「新的C#視窗應用」序列是在一個下面的方式修改創建的窗口形式以下修改:

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

} 

如果我按F5在IDE中,然後,如我所料,我看到一個消息框說異常被捕獲,並且應用程序退出。

如果我去調試(或釋放)/斌並啓動可執行文件,我看到標準的「未處理的異常」窗口,這意味着我的異常處理程序不起作用。

很明顯,這與異常從Application.Run被調用的另一個線程拋出有關。但問題依然存在 - 爲什麼行爲會因應用程序是從IDE還是從命令行運行而有所不同? 確保應用程序中沒有未處理的例外的最佳做法是什麼?

+0

@Corvin:如果你覺得你的問題得到了解決方案,請檢查一個被接受的答案。 – 2010-04-28 06:55:11

回答

10

正常情況下,Application.ThreadException將處理Load事件中的異常。你將得到提供Quit和Continue選項的ThreadExceptionDialog。

但是,當連接調試器時不行。在這種情況下,顯示對話框的消息循環中的catch子句被故意禁用。這是必要的,因爲如果在調試程序時彈出對話框,將很難排除異常。哪個捕手不再活躍,您的Main()方法中的catch子句現在可以捕捉異常。

可以通過在Main()方法中使用Application.SetUnhandledExceptionMode()來使其一致。你不應該,如果你這樣做,異常真的難以調試。如果您想自定義UI線程異常處理,那麼你應該註冊自己的Application.ThreadException處理程序:

if (!System.Diagnostics.Debugger.IsAttached) 
    Application.ThreadException += myThreadException; 

俘獲工作線程未處理的異常需要AppDomain.UnhandledException處理程序。它們不可恢復。

還要小心64位Windows中的一個錯誤,當調試器被連接時,Load事件中的異常會被吞下而無需診斷。強制AnyCPU模式以避免陷阱。

+0

@Hans - 你是指'Form.Load'事件嗎?順便說一句,寫得不錯。 – 2010-04-28 06:56:39

+0

@彼得:是的。謝謝! – 2010-04-28 09:02:09