2011-11-16 474 views
17

我已經實現了一個具有DLL庫的軟件,其中包含一大類包含我軟件所有方法的類。WinForms全局異常處理?

現在我想能夠處理一些全局錯誤,如錯誤#26這是所有這些類上沒有網絡相關錯誤,而不是去每個類,並添加它。怎麼做 ?

回答

12

如果#26是例外,那麼您可以使用AppDomain.CurrentDomain.UnhandledException事件。如果它只是一個回報值,那麼我認爲沒有機會在全球範圍內處理這個問題。

+1

如果把這段代碼,如果您有任何引用,或者你可以發佈一個例子,我會很滿。 – ykh

+0

請參閱我答案中的MSDN鏈接。它有一個例子:http://msdn.microsoft.com/en-us/library/system.appdomain.unhandledexception.aspx – gideon

23

由於它是一個winforms應用程序,您可以將Application.Run(new MainForm());放在try catch塊中。

static void Main() 
{ 
try { 
Application.Run(new MainForm()); 
} catch(SystemException)//just as an example 
{ 
//log or handle the error here. 
} 
} 

我不知道這種解決方案會造成什麼影響,但我只是告訴過你需要什麼。其他選項訂閱Application.ThreadException事件。

更多在這裏閱讀:unhandledexceptions

還有AppDomain.UnhandledException,你應該閱讀here on MSDN之間的區別。

從MSDN:

對於某些應用模型中,UnhandledException事件可以由其他事件,如果在主應用程序線程中發生未處理的異常搶佔。

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

-1

由於上面顯示的延伸,我使用以下命令:

try 
{ 
    Application.Run(new FormMain()); 
} 
catch (Exception ex) 
{ 
    RoboReporterConstsAndUtils.HandleException(ex); 
} 

...其中HandleException()方法可以是這樣的:

internal static void HandleException(Exception ex) 
{ 
    var exDetail = String.Format(ExceptionFormatString, 
     ex.Message, 
     Environment.NewLine, 
     ex.Source, 
     ex.StackTrace, 
     ex.InnerException); 

    ExceptionLoggingService.Instance.LogAndEmailExceptionData(string.Format("{0}: {1}: {2}", 
     DateTime.Now.ToLongDateString(), GetVersionInfo(), exDetail)); 
} 

另一種方式對皮膚這個貓是:

static void Main() 
{ 
    Application.EnableVisualStyles(); 
    Application.SetCompatibleTextRenderingDefault(false); 
    AppDomain.CurrentDomain.UnhandledException += Unhandled; 
    Application.Run(new FormMain()); 
} 

static void Unhandled(object sender, UnhandledExceptionEventArgs exArgs) 
{ 
    ExceptionLoggingService.Instance.LogAndEmailMessage(String.Format 
     ("From application-wide exception handler: {0}", exArgs.ExceptionObject)); 
} 

當然,你可以在Unhandled()方法中做任何你想做的事情。

6

隨着Centralized Exception Handling在C#Windows應用程序的參考,我發現了很好的解決方案之一:

static class Program 
{ 
    [STAThread] 
    static void Main() 
    { 
     // Add handler to handle the exception raised by main threads 
     Application.ThreadException += 
     new System.Threading.ThreadExceptionEventHandler(Application_ThreadException); 

     // Add handler to handle the exception raised by additional threads 
     AppDomain.CurrentDomain.UnhandledException += 
     new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException); 

     Application.EnableVisualStyles(); 
     Application.SetCompatibleTextRenderingDefault(false); 
     Application.Run(new Form1()); 

     // Stop the application and all the threads in suspended state. 
     Environment.Exit(-1);    
    } 

    static void Application_ThreadException 
     (object sender, System.Threading.ThreadExceptionEventArgs e) 
    {// All exceptions thrown by the main thread are handled over this method 

     ShowExceptionDetails(e.Exception); 
    } 

    static void CurrentDomain_UnhandledException 
     (object sender, UnhandledExceptionEventArgs e) 
    {// All exceptions thrown by additional threads are handled in this method 

     ShowExceptionDetails(e.ExceptionObject as Exception); 

     // Suspend the current thread for now to stop the exception from throwing. 
     Thread.CurrentThread.Suspend(); 
    } 

    static void ShowExceptionDetails(Exception Ex) 
    { 
     // Do logging of exception details 
     MessageBox.Show(Ex.Message, Ex.TargetSite.ToString(), 
       MessageBoxButtons.OK, MessageBoxIcon.Error); 
    } 
} 

在上面的類,我們將附上一個事件處理兩個事件。一旦主要方法啓動,最好附加這些事件。

Application.ThreadException - 在主線程中引發異常時會引發此事件。如果我們添加一個事件處理程序,那麼通過該方法處理異常。

AppDomain.CurrentDomain.UnhandledException - 當一個異常在應用程序中使用額外的線程將引發此事件將得到提升。這裏情況越糟糕,只要處理程序的執行結束,異常再次拋出,而應用程序結束。這需要處理。在這裏,我使用了一些代碼來處理這種情況,並繼續執行應用程序而不中斷。

我用來克服這種情況的邏輯只是暫停事件處理程序中的線程,以便應用程序繼續正常工作。在暫停此線程中再次出現問題。當主窗體關閉時,應用程序通常需要退出,但由於線程處於暫停狀態,應用程序仍將保持運行狀態。因此,要完全退出應用程序並停止該過程,必須在主方法結束之前調用Environment.Exit(-1)。

3

首先,你應該加上:

Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException); 

之後,你可以捕獲異常,例如:

[STAThread] 
    static void Main() 
    { 

     Application.EnableVisualStyles(); 
     Application.SetCompatibleTextRenderingDefault(false); 
     Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException); 
     Application.ThreadException += ApplicationThreadException; 
     AppDomain.CurrentDomain.UnhandledException += CurrentDomainOnUnhandledException; 

     if (DataBaseMNG.Init()) 
     { 
      Application.Run(new MainForm()); 
     } 
    } 

    /// <summary> 
    /// Global exceptions in Non User Interfarce(other thread) antipicated error 
    /// </summary> 
    /// <param name="sender"></param> 
    /// <param name="e"></param> 
    private static void CurrentDomainOnUnhandledException(object sender, UnhandledExceptionEventArgs e) 
    { 
     var message = 
      String.Format(
       "Sorry, something went wrong.\r\n" + "{0}\r\n" + "{1}\r\n" + "please contact support.", 
       ((Exception)e.ExceptionObject).Message, ((Exception)e.ExceptionObject).StackTrace); 
     MessageBox.Show(message, @"Unexpected error"); 
    } 

    /// <summary> 
    /// Global exceptions in User Interfarce antipicated error 
    /// </summary> 
    /// <param name="sender"></param> 
    /// <param name="e"></param> 
    private static void ApplicationThreadException(object sender, ThreadExceptionEventArgs e) 
    { 
     var message = 
      String.Format(
       "Sorry, something went wrong.\r\n" + "{0}\r\n" + "{1}\r\n" + "please contact support.", 
       e.Exception.Message, e.Exception.StackTrace); 
     MessageBox.Show(message, @"Unexpected error"); 
    }