2015-09-04 18 views
2

我想爲我的WinForms應用程序中的任何線程設置所有未處理異常的處理程序方法。我自己不創建任何應用程序域。如何在WinForms應用程序中正確捕獲所有未處理的異常

UnhandledException文件,我需要通過Application.SetUnhandledExceptionMode方法來設置UnhandledExceptionMode.ThrowException模式捕捉主線程的例外太多:

在使用Windows窗體應用程序,在 主應用程序線程未處理的異常導致的應用。拋出ThreadException事件到 。如果處理此事件,默認行爲是 未處理的異常不會終止應用程序,儘管 應用程序處於未知狀態。在這種情況下,不會引發 UnhandledException事件。通過使用應用程序配置文件或通過使用Application.SetUnhandledExceptionMode方法將模式更改爲 ,可以將模式更改爲 UnhandledExceptionMode.ThrowException之前的ThreadException事件 處理程序已掛鉤。這僅適用於主應用程序 線程。該UnhandledException事件引發未處理的異常 在其他線程

所以拋出,結果代碼如下所示:

public static void UnhandledExceptionEventHandler(object sender, UnhandledExceptionEventArgs e) 
    { 
     // ... 
    } 

    [STAThread] 
    static void Main(string[] args) 
    { 
     Application.SetUnhandledExceptionMode(UnhandledExceptionMode.ThrowException); 
     AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(UnhandledExceptionEventHandler); 

     Application.EnableVisualStyles(); 
     Application.SetCompatibleTextRenderingDefault(false); 
     Application.Run(new MainForm(pathToCheck)); 
    } 

是否確定?它會捕獲來自任何線程的所有未處理的異常(包括主線程,UI線程和由Task類創建的所有線程)嗎?我是否正確理解文檔?

是的,我看到像this的問題在這裏,但我不明白爲什麼要我也用下面的代碼:

Application.ThreadException += new  
    ThreadExceptionEventHandler(ErrorHandlerForm.Form1_UIThreadException); 
+1

請參閱[本答案](http://stackoverflow.com/a/6115595/43846)爲什麼你想要處理ThreadException。 – stuartd

+0

@stuartd根據這個鏈接,我也可以通過'SetUnhandledExceptionMode'方法強制UI線程異常,所以我並不需要指定'ThreadException'處理程序。我對嗎? – FrozenHeart

+0

由於第三方庫的原因,可能會有異常,所以它總是建議處理ThreadException。 –

回答

1

您應該訂閱這兩個事件。請注意,即使這不會自動捕獲其他線程的所有內容。例如,當代理被異步調用時,只有在調用EndInvoke時,異常纔會傳播到調用者線程。

[STAThread] 
    static static void Main(string[] args) 
    { 
     AppDomain.CurrentDomain.UnhandledException += 
      (sender, args) => HandleUnhandledException(args.ExceptionObject as Exception); 
     Application.ThreadException += 
      (sender, args) => HandleUnhandledException(args.Exception); 
    } 

    static void HandleUnhandledException(Exception e) 
    { 
     // show report sender and close the app or whatever 
    } 
+0

「你應該訂閱這兩個事件」 - 爲什麼? 「只有在調用EndInvoke時纔會將異常傳播給調用者線程」 - 如果我完全不顯式調用EndInvoke方法,該怎麼辦? – FrozenHeart

+0

*爲什麼*:因爲他們從不同來源收集異常。請參閱https://msdn.microsoft.com/en-us/library/system.windows.forms.application.threadexception%28v=vs.110%29.aspx * EndInvoke *:通常情況下,您不應該擔心,在已經工作的應用程序'BeingInvoke'和'EndInvoke'總是被成對調用。否則,通話結果也會丟失。請參閱http://stackoverflow.com/questions/7492741/c-sharp-asynchronous-call-without-endinvoke – taffer

+0

我應該只在'main'方法中設置'ThreadException'嗎?它會啓用此功能以適應所有未來的任務和線程嗎? – FrozenHeart

相關問題