2008-09-30 63 views
2

請注意,我意識到這已被解決here。這篇文章討論了.NET 1.1中的異常處理,同時暗示了針對> .NET 2.0的更好的解決方案,所以這個問題特別針對更新的.NET版本。有沒有辦法在WinForms .NET 3.5應用程序中爲未處理的異常定義動作?

我有一個Windows窗體應用程序,預計會頻繁地意外丟失與數據庫的連接,在這種情況下,它將重置爲初始狀態。

我已經通過我的自定義DBWrapper對象上的一組裝飾器來進行錯誤日誌記錄,重試連接等。然而,在這之後,我想讓錯誤落入堆棧。一旦它到達頂部並且未被處理,我希望它被吞下,並執行我的ApplicationResetter.Reset()方法。

誰能告訴我如何做到這一點?

如果這是不可能的,那麼是否至少有一種方法可以解決這個問題,而不會引入ApplicationResetter對每個可能收到這樣的錯誤的類的依賴,而且實際上並沒有關閉並重新啓動我的應用程序(這看起來很醜陋) ?

回答

0

對於Windows窗體線程(其中調用Application.Run()),在主要的開始分配ThreadException處理器() 。此外,我發現有必要調用SetUnhandledExceptionMode:

Application.SetUnhandledExceptionMode(UnhandledExceptionMode.Automatic); 
Application.ThreadException += ShowUnhandledException; 
Application.Run(...); 

這是一個示例處理程序。我知道這不是你要找的,但它顯示處理程序的格式。請注意,如果您希望異常是致命的,則必須顯式調用Application.Exit()。

static void ShowUnhandledException(object sender, ThreadExceptionEventArgs t) 
{ 
    Exception ex = t.Exception; 
    try { 
     // Build a message to show to the user 
     bool first = true; 
     string msg = string.Empty; 
     for (int i = 0; i < 3 && ex != null; i++) { 
      msg += string.Format("{0} {1}:\n\n{2}\n\n{3}", 
       first ? "Unhandled " : "Inner exception ", 
       ex.GetType().Name, 
       ex.Message, 
       i < 2 ? ex.StackTrace : ""); 
      ex = ex.InnerException; 
      first = false; 
     } 
     msg += "\n\nAttempt to continue? (click No to exit now)"; 

     // Show the message 
     if (MessageBox.Show(msg, "Unhandled exception", MessageBoxButtons.YesNo, MessageBoxIcon.Error) == DialogResult.No) 
      Application.Exit(); 
    } catch (Exception e2) { 
     try { 
      MessageBox.Show(e2.Message, "Fatal error", MessageBoxButtons.OK, MessageBoxIcon.Stop); 
     } finally { 
      Application.Exit(); 
     } 
    } 
} 
2

警告:不熟悉的3.5然而,有可能是一個更好的答案...

...但我的理解是,在活動時間內到達未處理的異常處理程序,該應用程序很可能將死 - 如果它不死,它可能是如此損壞,它應該無論如何死

如果你已經在處理一個db-not-there的情況下,並讓其他異常通過,那麼應用程序應該死因爲它可能不穩定

+0

我處理由重試的情況和記錄它,但是之後做我的DBWrapper.GetDataSet()仍然有或者返回的東西給客戶或拋出一個錯誤。如果我拋出那麼錯誤會冒泡,除非我抓住需要重置器依賴項的東西。我希望儘可能高。 – 2008-09-30 19:47:32

+0

如果在三個等待 - 重試周期後未能找到數據庫,則返回null並讓調用者檢查該數據庫。否則,拋出一個自定義的異常,並讓應用程序死亡 - 沒有應用程序可以彌補不穩定/無法訪問的數據庫。 – 2008-09-30 20:12:20

+0

但就是這一點,我可以返回null或我可以拋出一個錯誤,無論調用類必須採取ApplicationResetter依賴 – 2008-09-30 20:26:30

1

也許Application.ThreadException事件將滿足您的需求:

static void Main() 
{ 
    Application.ThreadException += Application_ThreadException; 
    //... 
} 

static void Application_ThreadException(object sender, System.Threading.ThreadExceptionEventArgs e) 
{ 
    // call ApplicationResetter.Reset() here 
} 
1

還有System.Windows.Forms.Application.ThreadException事件和System.AppDomain.CurrentDomain.UnhandledException事件。

正如史蒂文提到的,這些將使您的應用程序處於未知狀態。除了將調用引發到try/catch塊中的異常之外,沒有其他辦法可以做到這一點。

0

在最新的MSDN問題未處理的異常的漂亮深入的解釋: September 2008

相關問題