2011-04-18 85 views
3

我的應用程序是Windows Forms .NET 4 C#TCP/IP服務器。它每天都會崩潰,並且每天都會發生一次通用Windows Server崩潰消息(按關閉關閉此應用程序)。我插入了以下代碼來捕獲可能導致此問題的任何異常,並且我將一個簡單的null對象插入一個定期調用的例程中以生成測試異常。C#未處理的異常處理程序,試圖寫入日誌文件

兩件事情:

  1. 當測試異常發生時,日誌代碼被擊中在調試器中,在文件被創建並寫入,和一切都很好。
  2. 沒有調試器,我得到一個「繼續或退出」 .NET堆棧跟蹤信息,並且無論哪個我選擇,是永遠不會創建或寫入文件。

的.NET消息對我沒用。我需要崩潰的日誌文件堆棧跟蹤。有誰知道我該怎麼做?謝謝。

static class Program 
{ 
    [STAThread] 
    static void Main(string[] rgszArgs) 
    { 
     //My exception handler 
     AppDomain.CurrentDomain.UnhandledException += 
      new UnhandledExceptionEventHandler(CatchUnhandledException); 

     Application.EnableVisualStyles(); 
     Application.SetCompatibleTextRenderingDefault(false); 
     Application.Run(new FormMain(rgszArgs)); 
    } 

    static void CatchUnhandledException 
     (object sender, UnhandledExceptionEventArgs e) 
    { 
     StreamWriter sw; 
     DateTime dtLogFileCreated = DateTime.Now; 
     Exception ex; 

     try 
     { 
      sw = new StreamWriter("crash-" + dtLogFileCreated.Day + dtLogFileCreated.Month 
         + dtLogFileCreated.Year + "-" + dtLogFileCreated.Second 
         + dtLogFileCreated.Minute + dtLogFileCreated.Hour + ".txt"); 

      ex = (Exception)e.ExceptionObject; 

      sw.WriteLine("### Server Crash ###"); 
      sw.WriteLine(ex.Message + ex.StackTrace); 
      sw.Close(); 
     } 
     finally 
     { 
      Application.Exit(); 
     } 
    } 
} 
+0

只是nitpicky,但我會拋出你的streamwriter.close()調用到終端或使用SW內的使用塊。 – 2011-04-19 01:20:08

回答

5

你想要Application.ThreadException事件。

在AppDomain unandled異常事件capturess未處理的異常拋出 - 例如通過Main方法引發的任何異常,但是Application.Run內部處理的例外 - 這意味着Application.Run不會拋出一個異常作爲例外的事件處理程序的結果,因此CatchUnhandledException永遠不會運行。

這意味着,如果ThreadException處理器能夠從異常的應用程序將繼續正常運行恢復(如果異常被拋出Application.Run就沒有痊癒的機會)。 由於我不明白這個行爲在調試時不同的原因。 。調試時,此行爲發生更改,以便引發異常,從而允許您在Visual Studio中立即調試異常 - 這就是爲什麼在調試時未處理的異常處理程序正在工作。

請注意,上述CatchUnhandledException處理程序捕獲您的應用程序域中後臺線程拋出的異常。請參閱Application.SetUnhandledExceptionMode

+0

工作完美,謝謝指引我在正確的方向。 – RawwrBag 2011-04-19 06:03:09

0

這是從MSDN上AppDomain.UnhandledException Event

與.NET Framework版本4起,則不會引發例外這一事件的過程中損壞的狀態,如堆棧溢出或訪問違規,除非事件處理程序是安全關鍵的並且具有HandleProcessCorruptedStateExceptionsAttribute特性。

難道這是它?

+0

我不這麼認爲......我插入了一個非常簡單的例外,它不應該被認爲是安全關鍵。 – RawwrBag 2011-04-19 02:28:45

1

我不得不猜測這是爲AppDomain.UnhandledException事件的事件處理程序。有一件事你絕對不能做的就是調用Application.Exit(),程序不再處於正確的狀態關閉,你必須調用Environment.Exit()。 Application.Exit()調用可能是「繼續或退出」消息的來源,聽起來像Winforms應用程序顯示的ThreadExceptionDialog,它在UI線程中遭受爐膛攻擊。

接下來的問題是,你傳遞給StreamWriter的構造函數中的參數。您沒有爲該文件指定完整的路徑名稱(如c:\ mumble \ foo.txt),它可能會嘗試將該文件寫入到您沒有寫入權限的目錄中。很可能在Vista或Win7上。或者該文件實際上已經寫入,但你無法找到它,因爲你不知道在哪裏看。

使用Environment.GetFolderPath()來接你知道你可以寫一個目錄。

+0

或使用事件日誌。這是爲了這樣的情況。 – tomfanning 2011-04-19 00:51:07

+0

@tomfanning對不起,我現在添加了全班。顯然是錯過了一個重要的信息。 – RawwrBag 2011-04-19 03:39:19

0

如果程序的狀態處於如此混亂的狀態,try/finally塊中的任何代碼都會破壞程序,那麼您也可以嘗試撥打Environment.FailFast("reason for failure here")。這將自動寫入事件日誌。