2011-04-23 22 views
65

到目前爲止,我只是在Program.cs入口點的Application.Run周圍放置了一個try/catch塊。這在調試模式下捕獲了所有異常,但是當我在沒有調試模式的情況下運行程序時,異常不再被處理。我得到未處理的異常框。我該如何製作能夠捕獲WinForms應用程序中所有「未處理」異常的東西?

我不希望發生這種情況。我希望在非調試模式下運行時捕獲所有異常。該程序有多個線程,最好來自它們的所有異常都被相同的處理程序捕獲;我想在數據庫中記錄異常。有沒有人有任何建議如何做到這一點?

回答

87

的例子來看看從ThreadException documentation

public static void Main(string[] args) 
{ 
    // Add the event handler for handling UI thread exceptions to the event. 
    Application.ThreadException += new  
    ThreadExceptionEventHandler(ErrorHandlerForm.Form1_UIThreadException); 

    // Set the unhandled exception mode to force all Windows Forms errors 
    // to go through our handler. 
    Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException); 

    // Add the event handler for handling non-UI thread exceptions to the event. 
    AppDomain.CurrentDomain.UnhandledException += new  
    UnhandledExceptionEventHandler(CurrentDomain_UnhandledException); 
} 

你可能也想不在調試時捕獲異常,因爲這樣可以更容易地進行調試。這是有點破解,但你可以包裝上面的代碼

if (!AppDomain.CurrentDomain.FriendlyName.EndsWith("vshost.exe")) { ... } 

爲了防止在調試時捕獲異常。

+1

我做了一個後臺工作,並且在dowork事件處理程序中,我暗中引起了一個空引用異常。然而它並沒有被AppDomain.CurrentDomain.UnhandledException捕獲,儘管設置了這些:Application.ThreadException + = new System.Threading.ThreadExceptionEventHandler(Application_ThreadException); Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException); AppDomain.CurrentDomain.UnhandledException + = new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException); – 2011-04-23 08:25:35

+3

@IsaacB,後臺工作人員本身捕獲異常。您甚至可以在RunWorkerCompleted中查看異常,查看RunCompletedEventArgs.Error屬性。 – 2011-04-23 08:33:46

+1

您可以通過將其添加到主窗體的OnLoad中來測試其他線程的異常處理。 new Thread(()=> {throw new Exception();})。Start(); – 2011-04-23 08:36:05

8

您可以使用NBug庫。用最少的設置是這樣的:

NBug.Settings.Destination1 = "Type=Mail;[email protected];[email protected];SmtpServer=smtp.mycompany.com;"; 
AppDomain.CurrentDomain.UnhandledException += NBug.Handler.UnhandledException; 
Application.ThreadException += NBug.Handler.ThreadException; 

你可以開始收集有關應用程序的所有未處理的錯誤,即使它部署到客戶端的信息。如果你不希望使用第三方庫,你要重視以下事件:

// These two should come before enabling visual styles or running the application 
AppDomain.CurrentDomain.UnhandledException += ... 
Application.ThreadException += ... 
... 
Application.Run(new Form1()); 
+1

。如果您有進一步的問題(http://www.nbusy.com/forum/f11/)或使用[nbug]標籤,請使用NBug項目論壇。 – 2011-04-23 06:11:10

+0

當然,您也可以訂閱UnhandledException事件的「常規」事件處理程序。請參閱http://msdn.microsoft.com/en-us/library/system.appdomain.unhandledexception.aspx – neo2862 2011-04-23 06:38:01

+0

Win7 + VS10的人,如果我訂閱這些事件訂閱不運行,而不是常規的Windows Vista/7對話框顯示「在線檢查解決方案」或「關閉程序」等。但如果我不訂閱,我會得到常規的.NET未處理異常窗口。這種情況發生在Release和Debug版本上,也嘗試設置Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);'不改變任何東西。 – gideon 2011-04-23 06:52:06

24

在NET 4中,某些例外是no longer caught by default;這些往往是指示可執行文件(可能是致命的)損壞狀態的異常,例如AccessViolationException。

嘗試在主要方法前使用[HandleProcessCorruptedStateExceptions]標記,例如

using System.Runtime.ExceptionServices.HandleProcessCorruptedStateExceptions 

[HandleProcessCorruptedStateExceptions] 
public static int Main() 
{ 
    try 
    { 
     // Catch any exceptions leaking out of the program 
     CallMainProgramLoop(); 
    } 
    catch (Exception e) // We could be catching anything here 
    { 
     System.Console.WriteLine(e.Message); 
     return 1; 
    } 
    return 0; 
    } 
+0

我可以使用'AppDomain.CurrentDomain.UnhandledException'和'Application.ThreadException'來處理'[HandleProcessCorruptedStateExceptions]'標籤嗎? – Kiquenet 2017-03-01 10:03:02

6

一個很好的例子可以在http://www.csharp-examples.net/catching-unhandled-exceptions/ 發現基本上,你的主要改變爲:不客氣

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

     Application.ThreadException += new ThreadExceptionEventHandler(Application_ThreadException); 
     Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException); 
     AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException); 

     Application.Run(new Form1()); 
    } 

    static void Application_ThreadException(object sender, ThreadExceptionEventArgs e) 
    { 
     MessageBox.Show(e.Exception.Message, "Unhandled Thread Exception"); 
    } 

    static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e) 
    { 
     MessageBox.Show((e.ExceptionObject as Exception).Message, "Unhandled UI Exception"); 
    } 
相關問題