2009-07-30 128 views
13

我有一個winforms應用程序.Winforms從Program.cs開始,我們有main()定義的地方。我把這段代碼放在try-catch塊中。爲什麼win32異常沒有被C#異常處理機制捕獲

[STAThread] 
    static void Main() 
    { 
     try 
     { 
      Application.EnableVisualStyles(); 
      Application.SetCompatibleTextRenderingDefault(false); 
      Application.Run(new frmSplash()); 
     } 
     catch (Exception ex) 
     { 
      MessageBox.Show(ex.Message); 
      if (ex.InnerException != null) 
      { 
       MessageBox.Show(ex.InnerException.ToString()); 
      } 
     } 
    } 

無論何時出現win32異常,此機制都會失敗並引發未處理的異常消息,並導致應用程序崩潰。
我對此代碼有兩個問題:

1)爲什麼win32異常沒有被捕獲。

2)在最高級別捕捉異常是一種好的做法。

+0

哇,我從來沒有真的想到這個,好問題和良好的答案:) – leppie 2009-07-30 09:35:32

+0

請在第二個問題上也評論。 – Rohit 2009-07-30 09:49:38

+0

也許你可以讓它成爲第二個SO問題;-) – Mac 2009-07-30 12:02:04

回答

0

您可能需要捕捉儘可能Win32Exception(或ExternalException)代替

http://msdn.microsoft.com/en-us/library/system.componentmodel.win32exception.aspx

我似乎記得Win32Exception從ExternalException但ExternalException繼承不從異常繼承這樣就不會被你的代碼捕獲。

編輯:請看爲什麼這是錯誤的其他答案!

編輯2:至於第二部分,由AnthonyWJones說這是禮貌,讓用戶知道,一個問題引起應用程序關閉,但我會建議使用簡單的英語語句用戶,並將異常堆棧記錄到您自己使用的日誌文件中。

+1

這兩個都是從異常派生的,因此表面上的問題應該可以工作。爲什麼它沒有看到我的答案。 – AnthonyWJones 2009-07-30 09:23:54

3

Application.Run的執行不會引發錯誤。這是發生在另一個線程上(或者至少是異步的)。

它的好主意是以友好的方式通知用戶應用程序已經失效,然後它完全消失,然而它不是一個好主意,只是趕上然後繼續。

3

雖然我不知道爲什麼你的catch塊不起作用嘗試使用Application ThreadException Event。這應該會捕獲應用程序線程中的任何錯誤在調用Application.Run之前添加一個事件處理程序。

對於第二個答案肯定是的。我開發和維護一個企業winforms應用程序,在後臺線程上與Web服務後端交談。如果任何Web服務調用崩潰處理應用程序threadexception(以及appdomain unhandledexception)事件,則會記錄並彈出一個業務用戶可以報告並允許它們繼續而不會導致應用程序崩潰的錯誤。

0

1)應該捕獲Win32異常。也許這個異常是從後臺線程或GC線程拋出的?

2)這取決於你的應用程序結構。例如,如果您的錯誤通知UI以某種方式與主窗體綁定(例如,您需要從工作線程調用UI線程),那麼在運行該消息的代碼之外的代碼塊中顯示UI會很愚蠢循環。但是,如果你的代碼示例是單線程的話,那就沒問題了。

1

嘗試在應用程序啓動(Application.Run)之前訂閱這些事件:

然後你可以擺脫你的try catch塊。


我認爲在最高級別捕捉異常是不好的做法,但是你無法避免它!在開發過程中(調試),這些異常不應該被捕獲,應用程序應該做最可能的事情(崩潰?)。在生產(發佈)中,即使發生未處理的異常,您也希望應用程序儘可能地降級。這是我爲DEBUG preprocessor variable發現的少數用途之一。