2013-12-03 33 views
4

我使用.NET 4.0框架維護傳統的C#Winform應用程序。該應用程序工作正常,但偶爾由於應用程序中的錯誤,當應用程序在數據庫中創建無效數據時,應用程序將無法正常工作。未處理的異常吞噬(調試器除外)

在某些情況下,我們將(無效/損壞)數據綁定到數據網格,當它試圖將空列映射到數據網格列時會導致大量錯誤。

「」類型的例外發生在mscorlib.dll但在用戶代碼中沒有處理

其他信息:對象不能從DBNull轉換爲其他類型。

除了

類型 'System.Reflection.TargetInvocationException' 的異常出現在System.Windows.Forms.dll中但在用戶代碼中沒有處理

的誤差導致一個不錯的彈出窗口顯示在Visual Studio調試器下運行,詳細說明錯誤以及允許我查看發生錯誤的行。

在這種特殊情況下,我知道這個問題是什麼,所以我可以很容易地糾正它。但是,這類錯誤通常發生在應用程序的其他部分,因此發生的情況並不總是很明顯,我的用戶並不總是提供良好的錯誤報告。爲了試圖解決這個問題,我想添加日誌記錄到應用程序(使用log4net),它適用於我們的情況,因爲每個用戶都有自己的應用程序副本,因此我可以在事實之後獲得每個用戶的日誌。

使用來自stackoverflow以及其他各種來源的提示,我發現了很多關於爲這些未處理的異常設置處理程序的好信息。不幸的是,我的處理程序沒有被要求處理大多數「未處理」的異常。

應用程序的主要相關部分如下:

static class Program { 
    private static readonly ILog log = LogManager.GetLogger("Main"); 

    static void Main() { 
     // Add some error handlers which log error data to the logfile 
     // 
     // For UI events (set the unhandled exception mode to force all Windows Forms 
     // errors to go through our handler) 
     Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException); 
     Application.ThreadException += new ThreadExceptionEventHandler(delegate(object s, ThreadExceptionEventArgs e) { 
      ExceptionLogger(e.Exception); 
     }); 
     // Non-UI thread exceptions 
     AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(delegate(object sender, UnhandledExceptionEventArgs e) { 
      ExceptionLogger(e.ExceptionObject as Exception); 
     }); 

     Application.EnableVisualStyles(); 
     Application.SetCompatibleTextRenderingDefault(false); 
     log.Debug("Starting Application"); 
     Application.Run(mainForm = new MainForm()); 
    } 

    private static void ExceptionLogger(Exception e) { 
     log.Error("Unhandled Error", e); 
     string errorMsg = "An application error occurred. Please contact the administrator with the following information:\n\n"; 
     errorMsg = errorMsg + e.Message + "\n\nStack Trace:\n" + e.StackTrace; 
     if (MessageBox.Show(errorMsg, "TLMS Error", MessageBoxButtons.AbortRetryIgnore, MessageBoxIcon.Stop) == DialogResult.Abort) 
      Application.Exit(); 
    } 

異常處理程序似乎如果我自己的代碼直接出現的錯誤的工作,但處理不叫,如果/當直接發生的錯誤在.NET庫中,並且我想要處理程序調用全部未處理的異常,包括我編寫的代碼以外的異常。

如果我可以在事件後重新創建調試器中的確切用戶步驟,那麼能夠使用調試器來追蹤錯誤是無價的。但是,ExceptionLogger在任何時候都不會被調用,無論是單獨運行還是在調試器內運行,並且沒有任何可視指示發生任何錯誤。由於例外情況被壓制,用戶有時直到太晚才意識到他們所做的一切都已經完全搞砸了,而且數據更加腐敗。

應用程序平臺正在構建並在x86上運行(顯然,如果在x64上運行,可能會丟失異常),並且應用程序已在64位和32位平臺上進行過測試,而且行爲沒有變化。

+0

您是否引用任何非託管代碼? – Paparazzi

+0

我們在一些較舊的Shockwave和Office庫中進行鏈接,儘管它們大部分時間都沒有使用。 – NaterTot

+0

看到這個[鏈接](http://stackoverflow.com/questions/545760/which-config-element-affects-exception-handling-with-unhandledexceptionmode-set) – ahazzah

回答

0

所以你只看到「但沒有處理」時,應用程序在調試器中運行。當它在調試器之外運行時,異常被抑制。如果我有這個正確的,我仍然認爲應用程序處理異常,因爲調試器有時會更改應用程序的行爲。

我確認InvalidCastException是.NET 4+處理異常的一組異常之一,如果異常上下文是非託管代碼。應用程序可以覆蓋此特殊處理(請參閱All about Corrupted State Exceptions in .NET 4),但調試器可能會忽略該覆蓋。這裏有很多網頁資源,另請參閱MSDN Magazine

編輯:如果您的應用程序用戶安裝了.NET 3.5或更低版本,則該應用程序無需應用上述資源中所述的覆蓋。

+0

我翻看整個應用程序,並且100%正面例外情況未被我的應用程序捕獲。感謝指針,我會研究CSE問題,看看我是否看到了這一點。 – NaterTot