2009-01-02 243 views
34

我想爲所有意外的異常設置一些處理程序,我可能沒有在代碼中捕獲異常。在Program.Main()我用下面的代碼:處理未處理的異常問題

AppDomain.CurrentDomain.UnhandledException 
    += new UnhandledExceptionEventHandler(ErrorHandler.HandleException); 

但它沒有按預期工作。當我在調試模式下啓動應用程序並拋出異常時,它確實調用了處理程序,但之後,Visual Studio中的異常幫助程序彈出,就好像發生異常而沒有進行任何處理。我在處理程序中嘗試了Application.Exit(),但它並沒有工作。

我想達成什麼是例外與我的處理程序進行處理,然後將應用程序很好地關閉。有沒有其他的方式來做到這一點,或者我用錯誤的方式使用上面的代碼?

回答

27

這是因爲你通過Visual Studio在調試模式下運行它。如果您在其他地方發佈並安裝您的應用程序,則只會處理您的全局異常處理程序。

6

請注意,未處理的異常仍然非常致命;你只能真正使用它來進行日誌記錄,或者可能是一些倉促的關閉。這個和Application.ThreadException都不能用作錯誤的全局接收器。

更好的方法是添加適當的處理 - 例如,在你的整個Main()邏輯。請注意,即使這個也無法捕捉到一些例外情況,例如表單加載期間的錯誤(這尤其令人討厭 - 您可以使用附加的調試器捕獲它們,但並非如此)。

+0

嗯,是的,當然我知道;) – agnieszka 2009-01-02 09:48:45

+0

那麼爲什麼不在他們的主要()? – 2009-01-02 10:05:36

31

通常我使用這樣的嘗試和捕獲所有意想不到的頂級例外。

using System; 

static class Program 
{ 
    [STAThread] 
    static void Main(string[] argv) 
    { 
    try 
    { 
     AppDomain.CurrentDomain.UnhandledException += (sender,e) 
     => FatalExceptionObject(e.ExceptionObject); 

     Application.ThreadException += (sender,e) 
     => FatalExceptionHandler.Handle(e.Exception); 

     // whatever you need/want here 

     Application.Run(new MainWindow()); 
    } 
    catch (Exception huh) 
    { 
     FatalExceptionHandler.Handle(huh); 
    } 
    } 

    static void FatalExceptionObject(object exceptionObject) { 
    var huh = exceptionObject as Exception; 
    if (huh == null) { 
     huh = new NotSupportedException(
     "Unhandled exception doesn't derive from System.Exception: " 
     + exceptionObject.ToString() 
    ); 
    } 
    FatalExceptionHandler.Handle(huh); 
    } 
} 

也許這是你找到有用的東西嗎?這個主代碼通過一個方法調用來路由所有三種捕獲意外的頂級異常的方法。您現在需要的是一個靜態類FatalExceptionHandler,其中包括您的頂級異常處理Handle方法。

真的,任何應用開發者都知道有真的只是兩兩件事要做有:

  1. 顯示/記錄異常像你認爲合適的
  2. 確保你退出/殺申請過程

如果您認爲項目二是奇怪的,請記住,我們只費心了真正出色的情況下做到這一點擺在首位。這些東西可能是需要更改您的應用程序以準確解決的錯誤。任何其他的異常處理 - 功能類型 - 應該在實際的程序代碼中降低,捕捉特定類型的異常,這是有道理的,並以有意義的方式處理它們。還有什麼應該泡到你的FatalExceptionHandler,使自己已知的,從損壞的狀態工作停止可能殘廢程序

死程序撒謊... ;-)

2

你要找也許什麼是Environment.Exit(int errorcode)

1

這種行爲是由設計。

但是的解決辦法。

要麼在處理程序中調用Process.GetCurrentProcess().Kill();,要麼就是不要讓處理程序結束。

退房的例子:

class Program 
{ 
    void Run() 
    { 
     AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException); 

     Console.WriteLine("Press enter to exit."); 

     do 
     { 
      (new Thread(delegate() 
      { 
       throw new ArgumentException("ha-ha"); 
      })).Start(); 

     } while (Console.ReadLine().Trim().ToLowerInvariant() == "x"); 


     Console.WriteLine("last good-bye"); 
    } 

    int r = 0; 

    void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e) 
    { 
     Interlocked.Increment(ref r); 
     Console.WriteLine("handled. {0}", r); 
     Console.WriteLine("Terminating " + e.IsTerminating.ToString()); 

     Thread.CurrentThread.IsBackground = true; 
     Thread.CurrentThread.Name = "Dead thread";    

     while (true) 
      Thread.Sleep(TimeSpan.FromHours(1)); 
     //Process.GetCurrentProcess().Kill(); 
    } 

    static void Main(string[] args) 
    { 
     Console.WriteLine("..."); 
     (new Program()).Run(); 
    } 
} 

這不應該成爲例外默認下沉,肯定。

但是這應該完成以優雅地報告異常。