我的应用程序是Windows Forms .NET 4 C#TCP / IP服务器。它每天都会崩溃一次,发生一般的Windows Server崩溃消息(按关闭以关闭此应用程序)。我插入以下代码来捕获可能导致此问题的任何异常,并将一个简单的null Object插入到一个定期调用以生成测试异常的例程中。
两件事:
.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 :(得分:5)
您想要Application.ThreadException事件。
AppDomain未发送的异常事件捕获抛出的未处理异常 - 例如Main
方法抛出的任何异常,但是Application.Run
在内部处理异常 - 这意味着Application.Run
不会抛出异常由于事件处理程序中的异常导致异常,因此永远不会运行CatchUnhandledException
。
这意味着如果ThreadException
处理程序能够从异常中恢复,则应用程序将继续正常运行(如果Application.Run
抛出异常,则无法恢复)。 由于我不明白的原因,这种行为在调试时有所不同。。调试时,此行为已更改,以便抛出异常,允许您在Visual Studio中立即调试异常 - 这就是您在调试时未处理的异常处理程序正在运行的原因。
请注意,上述CatchUnhandledException
处理程序将捕获应用程序域中后台线程抛出的异常。
答案 1 :(得分:1)
我必须猜测这是AppDomain.UnhandledException事件的事件处理程序。你绝对不能做的一件事就是调用Application.Exit(),程序不再处于正确状态以便很好地关闭,你必须调用Environment.Exit()。 Application.Exit()调用可能是“继续或退出”消息的来源,听起来像Winforms应用程序显示的ThreadExceptionDialog,它在UI线程中遭受了一次炉膛攻击。
下一个问题是传递给StreamWriter构造函数的参数。您没有为文件指定完整路径名(例如c:\ mumble \ foo.txt),它可能会尝试将文件写入您没有写访问权限的目录。很可能在Vista或Win7上。或者文件实际上已经写好了,但你找不到它,因为你不知道在哪里看。
使用Environment.GetFolderPath()选择一个您知道可以写入的目录。
答案 2 :(得分:0)
这是来自AppDomain.UnhandledException Event上的MSDN:
从.NET Framework版本4开始,不会针对损坏进程状态的异常(例如堆栈溢出或访问冲突)引发此事件,除非事件处理程序是安全关键的并且具有HandleProcessCorruptedStateExceptionsAttribute属性。 / p>
这可能吗?
答案 3 :(得分:0)
如果你的程序状态混乱,try / finally块中的任何代码都会破坏你的程序,你也可以尝试调用Environment.FailFast("reason for failure here"
)。这将自动写入事件日志。