簡體   English   中英

C#未處理的異常處理程序,嘗試寫入日志文件

[英]C# unhandled exception handler, attempting to write to log file

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

兩件事情:

  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();
        }
    }
}

您需要Application.ThreadException事件。

AppDomain未發送的異常事件捕獲拋出的未處理異常 - 例如Main方法拋出的任何異常,但Application.Run內部處理異常 - 這意味着Application.Run不會因事件處理程序中的異常而拋出異常,所以永遠不會運行CatchUnhandledException

這意味着如果ThreadException處理程序能夠從異常中恢復,則應用程序將繼續正常運行(如果Application.Run拋出異常,則無法恢復)。 由於我不明白的原因,這種行為在調試時是不同的。 調試時,此行為已更改,以便拋出異常,允許您在Visual Studio中立即調試異常 - 這就是您的未處理異常處理程序在調試時正在運行的原因。

請注意,上面的CatchUnhandledException處理程序捕獲應用程序域中后台線程拋出的異常。

另請參見Application.SetUnhandledExceptionMode

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

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

使用Environment.GetFolderPath()選擇一個您知道可以寫入的目錄。

這是來自MSDN的AppDomain.UnhandledException事件

從.NET Framework版本4開始,不會針對損壞進程狀態的異常(例如堆棧溢出或訪問沖突)引發此事件,除非事件處理程序是安全關鍵的並且具有HandleProcessCorruptedStateExceptionsAttribute屬性。

這可能嗎?

如果你的程序狀態混亂,try / finally塊中的任何代碼都會破壞你的程序,你也可以嘗試調用Environment.FailFast("reason for failure here" )。 這將自動寫入事件日志。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM