0

我有一个非常令人沮丧的问题。我正在编写一个 Windows 服务,它的作用类似于 TCPServer(我不确定技术术语,但该服务通过 tcp 处理一组客户端之间的通信)。

我的问题是服务随机崩溃(至少我不知道是什么原因导致异常)并且 Windows 应用程序日志包含 VsJITDebugger (EventID 4096) 错误消息说:

    SDUNoteTCPServerService.exe [1028] 中出现未处理的 win32 异常。刚进-       
    调试此异常的时间失败并出现以下错误:无法调试器
    因为没有用户登录而启动。

我不是 100% 确定 VsJITDebugger 是什么,但据我通过谷歌搜索发现 VsJITDebugger 是某种使用 Visual Studio 来澄清未处理异常的工具。有时我还会在 VsJITDebugger 错误消息之前看到以下 .Net Runtime (EventID: 1026) 错误消息:

    应用程序:SDUNoteTCPServerService.exe
    框架版本:v4.0.30319
    说明:进程因未处理的异常而终止。
    异常信息:System.ComponentModel.Win32Exception
    堆:
       在 System.Diagnostics.EventLogInternal.InternalWriteEvent(UInt32,UInt16,     
    System.Diagnostics.EventLogEntryType、System.String[]、Byte[]、System.String)
       在 System.Diagnostics.EventLogInternal.WriteEntry(System.String,
    System.Diagnostics.EventLogEntryType,Int32,Int16,字节 [])
       在 System.Diagnostics.EventLog.WriteEntry(System.String,      
    System.Diagnostics.EventLogEntryType, Int32)
       在    
    TCPServer.TCPServerListener+AsynchronousSocketListener.WriteCustomSocketObjectMessagesToLog
    (System.String, System.Diagnostics.EventLogEntryType, Int32)
       在 TCPServer.TCPServerListener+CustomSocketObject.SendMessageToClientThread()
       在 System.Threading.ThreadHelper.ThreadStart_Context(System.Object)
       在 System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext,     
    System.Threading.ContextCallback,System.Object,布尔值)
       在 System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext,   
    System.Threading.ContextCallback, System.Object)
       在 System.Threading.ThreadHelper.ThreadStart()

如 .Net 运行时错误消息中所述,当我尝试在 EventLog 中写入有关捕获的异常的详细信息时,会引发未处理的错误。异常总是在套接字的 BeginReceive 方法的回调函数中抛出。

我不知道为什么这个异常首先会导致服务崩溃,因为我在 Socket.BeginReceive 方法的回调函数中使用 try{}catch(Exception) 来捕获一般异常,但我无法提取任何关于捕获的异常,因为这个未处理的异常被抛出。

任何想法可能是什么问题?感谢所有回复。

注意:该服务在 Windows Server 2003 (SP2) 上运行。安装了 Visual Studio 2008。

编辑:WriteCustomSocketObjectMessagesToLog 看起来像这样(事件日志对象是 AsynchronousSocketListener 类的属性):

    private void WriteExceptionToLog(string customstartmessage, Exception ex)
    {
        尝试
        {
            eventlog.WriteEntry(customstartmessage, EventLogEntryType.Error);
            eventlog.WriteEntry(ex.Message, EventLogEntryType.Error, 5);
            eventlog.WriteEntry(ex.Source, EventLogEntryType.Error, 5);
            eventlog.WriteEntry(ex.StackTrace, EventLogEntryType.Error, 5);
        }
        捕捉(例外)
        {
            eventlog.WriteEntry("报告异常失败", EventLogEntryType.Error);
       }
    }

编辑2:

我弄清楚了问题所在。事件日志报告已满。难怪那时我不能写信给它。我通过将类库转换为控制台应用程序发现了问题。当我开始编写 TCPServer 类时,我也这样做了,但当时我使用 WriteLine 方法将错误写入控制台。这次控制台应用程序写入创建的事件日志,未处理的异常被写入控制台(如果这是控制台应用程序的默认行为,我不这样做,因为我没有为此进行任何编码)。我的 Windows 服务中未处理的错误很可能是这样的:

    未处理的异常:System.ComponentModel.Win32Exception:事件日志文件已满
       在 System.Diagnostics.EventLogInternal.InternalWriteEvent(UInt32 eventID,UInt16 类别,EventLogEntryType 类型,String[] 字符串,Byte[] rawData,String currentMachineName)
       在 System.Diagnostics.EventLogInternal.WriteEntry(字符串消息,EventLogEntryType 类型,Int32 eventID,Int16 类别,Byte[] rawData)
       在 System.Diagnostics.EventLog.WriteEntry(字符串消息)
       在 TCPServer.Program.Main(String[] args)

现在我只需要处理这个可能。处理此错误的更好解决方案是什么?每次抛出错误时以编程方式保存和清空事件日志?无限增加事件日志大小(这可能是个好主意吗?)?还有其他建议吗?

4

3 回答 3

1

如第二次编辑中所写,我发现问题是尝试写入事件日志时已满。我记录了很多,EventLog 的默认行为是 512 左右的 MaximumKilobytes 并保留超过 7 天的条目。我更改了配置,使 MaximumKilobytes 等于 25 MB,并根据需要覆盖条目。

于 2013-09-03T07:46:06.173 回答
0

如果要捕获异常,则需要在AsynchronousSocketListener.WriteCustomSocketObjectMessagesToLog. 该类AsynchronousSocketListener嵌套在TCPServerListener命名TCPServer空间中。我假设这个类是你或你的组织已经实施的。

不幸的是,在一些尝试写入事件日志的代码中会引发异常,因此如果异常的根本原因是内存耗尽,那么捕获异常并尝试记录它可能会有些困难。

查看类InternalWriteEvent中的 .NET 4.0 源代码System.Diagnostics.EventLogInternal似乎只有一个地方Win32Exception可以抛出 a ,那就是ReportEvent函数调用失败。

Win32Exception包含 Windows 错误代码。根据ReportEvent文档,可能有四个错误代码:

  • ERROR_INVALID_PARAMETER (87)
  • ERROR_NOT_ENOUGH_MEMORY (8)
  • RPC_S_INVALID_BOUND (1734)
  • RPC_X_BAD_STUB_DATA (1783)
  • 还有其他错误代码的可能性

发现错误代码Win32Exception应该可以帮助您了解问题的根源。

于 2013-09-02T13:28:39.617 回答
0

为您的 AppDomain UnhandledException 事件定义一个处理程序:

AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(MyHandler);

void MyHandler(object sender, UnhandledExceptionEventArgs e)
{
    // See the exception context here using e.ExceptionObject 
}
于 2013-09-02T13:16:00.810 回答