问题描述
|
我的应用程序是Windows Forms .NET 4 C#TCP / IP服务器。每天都有一次普通Windows Server崩溃消息崩溃(按close关闭此应用程序)。我插入了以下代码以捕获可能导致此异常的任何异常,并将简单的null对象插入到例程中,该例程会定期调用以生成测试异常。
两件事情:
当发生测试异常时,在调试器中命中日志代码,创建并写入文件,一切都很好。
没有调试器,我将收到“继续或退出” .NET stacktrace消息,并且无论选择哪个选项,都不会创建或写入文件。
.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
方法抛出的任何异常,但是however2ѭ内部处理异常),这意味着Application.Run
不会由于事件处理程序中的异常而抛出异常,因此CatchUnhandledException
从不运行。
这意味着,如果ThreadException
处理程序能够从异常中恢复,则应用程序将继续正常运行(如果Application.Run
抛出了异常,则没有恢复的机会)。出于某种原因,我无法理解调试时的行为。.调试时,此行为已更改,因此引发了异常,使您可以在Visual Studio中立即调试异常-这就是为什么未处理的异常处理程序在运行时调试。
请注意,上面的“ 4”处理程序将捕获应用程序域中后台线程引发的异常。
另请参见Application.SetUnhandledExceptionMode。,我不得不猜测这是AppDomain.UnhandledException事件的事件处理程序。您绝对不能做的一件事是调用Application.Exit(),程序不再处于正确关闭的正确状态,您必须调用Environment.Exit()。 Application.Exit()调用可能是\“ continue or quit \”消息的来源,听起来像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\"
。这将自动写入事件日志。