简体   繁体   English

使用catch时Windows Service中未处理的异常(异常)

[英]Unhandled exception in Windows Service when using catch(Exception)

I am having a very frustrating problem. 我有一个非常令人沮丧的问题。 I am writting a Windows Service, which acts like a TCPServer (I am not sure about the technical term, but the service handles communications via tcp between a set of clients). 我正在编写一个Windows服务,该服务的行为类似于TCPServer(我不确定技术术语,但该服务处理一组客户端之间通过tcp进行的通信)。

My problem is that the service crashes randomly (at least I don't know what causes the exception) and the windows application log contains a VsJITDebugger (EventID 4096) error message saying: 我的问题是服务随机崩溃(至少我不知道是什么原因导致了异常),并且Windows应用程序日志中包含一条VsJITDebugger(EventID 4096)错误消息,内容为:

An unhandled win32 exception occurred in SDUNoteTCPServerService.exe [1028]. Just-In-       
    Time debugging this exception failed with the following error: Debugger could not be 
    started because no user is logged on.

I am not a 100 % sure what the VsJITDebugger is, but as far as I have found out by googling the VsJITDebugger is some kind of tool that uses Visual Studio to clarify unhandled exceptions. 我不是100%知道VsJITDebugger是什么,但是据我通过谷歌搜索发现,VsJITDebugger是某种使用Visual Studio来澄清未处理异常的工具。 Sometimes I also see the following .Net Runtime (EventID: 1026) error message just before the VsJITDebugger error message: 有时,在VsJITDebugger错误消息之前,我还会看到以下.Net运行时(EventID:1026)错误消息:

Application: SDUNoteTCPServerService.exe
    Framework Version: v4.0.30319
    Description: The process was terminated due to an unhandled exception.
    Exception Info: System.ComponentModel.Win32Exception
    Stack:
       at System.Diagnostics.EventLogInternal.InternalWriteEvent(UInt32, UInt16,     
    System.Diagnostics.EventLogEntryType, System.String[], Byte[], System.String)
       at System.Diagnostics.EventLogInternal.WriteEntry(System.String, 
    System.Diagnostics.EventLogEntryType, Int32, Int16, Byte[])
       at System.Diagnostics.EventLog.WriteEntry(System.String,      
    System.Diagnostics.EventLogEntryType, Int32)
       at    
    TCPServer.TCPServerListener+AsynchronousSocketListener.WriteCustomSocketObjectMessagesToLog
    (System.String, System.Diagnostics.EventLogEntryType, Int32)
       at TCPServer.TCPServerListener+CustomSocketObject.SendMessageToClientThread()
       at System.Threading.ThreadHelper.ThreadStart_Context(System.Object)
       at System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext,     
    System.Threading.ContextCallback, System.Object, Boolean)
       at System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext,   
    System.Threading.ContextCallback, System.Object)
       at System.Threading.ThreadHelper.ThreadStart()

As stated in the .Net Runtime error message the unhandled error is thrown when I try to write details about the caught exception in an EventLog. 如.Net运行时错误消息中所述,当我尝试在EventLog中编写有关捕获的异常的详细信息时,将引发未处理的错误。 The exception is always thrown in the callback function of a socket's BeginReceive method. 总是在套接字的BeginReceive方法的回调函数中引发异常。

I don't know why this exception is crashing the service in the first place, because I am catching generic exceptions using try{}catch(Exception) in the Socket.BeginReceive method's callback function, but I am not able to extract any information about the caught exception, because of this unhandled exception getting thrown. 我不知道为什么该异常首先会使服务崩溃,因为我在Socket.BeginReceive方法的回调函数中使用try {} catch(Exception)捕获了通用异常,但是我无法提取有关以下内容的任何信息捕获的异常,因为此未处理的异常将被抛出。

Any ideas what the problem might be? 任何想法可能是什么问题? All replies are appreciated. 所有答复表示赞赏。

Note: The service is running on a Windows Server 2003 (SP2). 注意:该服务正在Windows Server 2003(SP2)上运行。 Visual Studio 2008 is installed. 已安装Visual Studio 2008。

Edit: The WriteCustomSocketObjectMessagesToLog looks like this (the eventlog object is a property of the AsynchronousSocketListener class): 编辑:WriteCustomSocketObjectMessagesToLog看起来像这样(eventlog对象是AsynchronousSocketListener类的属性):

private void WriteExceptionToLog(string customstartmessage, Exception ex)
    {
        try
        {
            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);
        }
        catch (Exception)
        {
            eventlog.WriteEntry("Failed reporting exception", EventLogEntryType.Error);
       }
    }

Edit 2: 编辑2:

I figured out what the problem is. 我想出了问题所在。 The eventlog is reported full. 报告事件日志已满。 No wonder I am not able to write to it then. 难怪我当时无法写信。 I found the problem by converting the class library to a console application. 我通过将类库转换为控制台应用程序发现了问题。 I also did this when I started writting the TCPServer class, but back then I wrote errors to Console using the WriteLine method. 当我开始编写TCPServer类时,我也这样做了,但是那时我使用WriteLine方法将错误写入控制台。 This time the console application writes to the created eventlog and the unhandled exception was written to Console (I don't if this is default behavior of a console application because I have not done any coding doing this). 这次,控制台应用程序将写入已创建的事件日志,并且未处理的异常已写入控制台(如果这是控制台应用程序的默认行为,则不会这样做,因为我没有做任何编码)。 The unhandled error in my Windows Service is most probably this: 我的Windows服务中未处理的错误很可能是这样的:

Unhandled Exception: System.ComponentModel.Win32Exception: The event log file is full
       at System.Diagnostics.EventLogInternal.InternalWriteEvent(UInt32 eventID, UInt16 category, EventLogEntryType type, String[] strings, Byte[] rawData, String currentMachineName)
       at System.Diagnostics.EventLogInternal.WriteEntry(String message, EventLogEntryType type, Int32 eventID, Int16 category, Byte[] rawData)
       at System.Diagnostics.EventLog.WriteEntry(String message)
       at TCPServer.Program.Main(String[] args)

Now I just need to handle this probably. 现在我可能只需要处理这个问题。 What would be the better solution to handle this error? 什么是处理此错误的更好的解决方案? Saving and emptying the eventlog programmatically everytime the error is thrown? 每次引发错误时,以编程方式保存和清空事件日志? Increase the eventlog size unlimited (is this possible and a good idea?)? 无限增加事件日志的大小(这可能是个好主意吗?)? Any other suggestions? 还有其他建议吗?

As written in the second edit I figured out the problem being the eventlog being full when trying to write to it. 如第二次编辑中所述,我发现问题是尝试写入事件日志时该事件日志已满。 I log A LOT and the default behavior of an EventLog is MaximumKilobytes of 512 or so and retaining entries newer than 7 days. 我记录了很多,EventLog的默认行为是MaximumKilobytes为512左右,并保留了7天以上的条目。 I changed the configuration so that the MaximumKilobytes is equal to 25 Megabytes and overwriting entries as needed. 我更改了配置,以使MaximumKilobytes等于25 MB,并根据需要覆盖条目。

Define a handler for your AppDomain UnhandledException event: 为您的AppDomain UnhandledException事件定义一个处理程序:

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

void MyHandler(object sender, UnhandledExceptionEventArgs e)
{
    // See the exception context here using e.ExceptionObject 
}

If you want to catch the exception you need to add an exception handler in AsynchronousSocketListener.WriteCustomSocketObjectMessagesToLog . 如果要捕获异常,则需要在AsynchronousSocketListener.WriteCustomSocketObjectMessagesToLog添加异常处理程序。 The AsynchronousSocketListener class is nested inside the TCPServerListener in the TCPServer namespace. AsynchronousSocketListener类嵌套在里面TCPServerListenerTCPServer命名空间。 I assume this class is something you or your organization has implemented. 我假设您或您的组织已经实施了该类。

Unfortunately, the exception is thrown in some code that tries to write to the event log so catching the exception and trying to log it may be somewhat hard if the root cause of the exception is say memory exhaustion. 不幸的是,在某些试图写入事件日志的代码中引发了异常,因此如果异常的根本原因是内存耗尽,则捕获异常并尝试记录异常可能会有些困难。

Looking into the .NET 4.0 source code for InternalWriteEvent in the System.Diagnostics.EventLogInternal class there seems to be only one place where a Win32Exception can be thrown and that is if the call to ReportEvent function fails. System.Diagnostics.EventLogInternal类中查看InternalWriteEvent的.NET 4.0源代码,似乎只有一个地方可以引发Win32Exception ,即对ReportEvent函数的调用失败。

The Win32Exception will contain a Windows error code. Win32Exception将包含Windows错误代码。 According to the ReportEvent documentation four error codes are possible: 根据ReportEvent文档,可能有四个错误代码:

  • ERROR_INVALID_PARAMETER (87) ERROR_INVALID_PARAMETER(87)
  • ERROR_NOT_ENOUGH_MEMORY (8) ERROR_NOT_ENOUGH_MEMORY(8)
  • RPC_S_INVALID_BOUND (1734) RPC_S_INVALID_BOUND(1734)
  • RPC_X_BAD_STUB_DATA (1783) RPC_X_BAD_STUB_DATA(1783)
  • There is also the possibility of other error codes 还有其他错误代码的可能性

Discovering the error code of the Win32Exception should hopefully help you understand the source of your problem. 发现Win32Exception的错误代码应该可以帮助您了解问题的根源。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM