繁体   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