2011-04-18 76 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")。这将自动写入事件日志。