.net应用程序

时间:2016-04-15 10:38:40

标签: .net multithreading windbg

我有一个申请。它是一个自托管的WCF应用程序。应用程序使用OpcNetApi连接到OPC服务器。 OpcNetApi在内部创建进程内COM组件以与OPC服务器通信。 WCF公开了用于同步读取和写入OPC服务器的方法。应用程序平台目标是x86,因为我们没有64位版本的COM组件。目标框架是.NET 4.0。 我们的应用程序还支持从opc服务器进行异步读取。为此,我们要求opc服务器组件通知我们是否更改了列表中的任何项目。即使没有更改项目,通知也被配置为每100毫秒不超过一次,并且至少每2000毫秒。通知来自附加到opc服务器类事件的事件处理程序。当我们收到来自opc服务器的通知时,我们将其转换并通过wcf调用传递给客户。

在生产中,我们在3台不同的机器上部署了3个应用程序实例。每个实例都连接到自己的opc服务器类型。 问题是一个特定的应用程序实例(每次在同一台机器上,使用相同的OPC服务器)停止工作。

停止工作意味着进程处于活动状态,但应用程序不再接受wcf调用,没有客户端接收通知,在日志中我没有关于应用程序活动的新条目。 应用程序突然停止工作。有时可能会在上次重启后的几天内发生,有时会在几周内发生。我没有注意到任何规律性,我也无法在本地重现。

当客户端调用wcf方法时,它会收到以下异常:

System.TimeoutException: The open operation did not complete within the allotted timeout of 00:01:00. The time allotted to this operation may have been a portion of a longer timeout. ---> System.TimeoutException: The socket transfer timed out after 00:00:59.9990234. You have exceeded the timeout set on your binding. The time allotted to this operation may have been a portion of a longer timeout. ---> System.Net.Sockets.SocketException: A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond
   at System.ServiceModel.Channels.SocketConnection.ReadCore(Byte[] buffer, Int32 offset, Int32 size, TimeSpan timeout, Boolean closing)
   --- End of inner exception stack trace ---
   at System.ServiceModel.Channels.SocketConnection.ReadCore(Byte[] buffer, Int32 offset, Int32 size, TimeSpan timeout, Boolean closing)
   at System.ServiceModel.Channels.SocketConnection.Read(Byte[] buffer, Int32 offset, Int32 size, TimeSpan timeout)
   at System.ServiceModel.Channels.ClientFramingDuplexSessionChannel.SendPreamble(IConnection connection, ArraySegment`1 preamble, TimeoutHelper& timeoutHelper)
   at System.ServiceModel.Channels.ClientFramingDuplexSessionChannel.DuplexConnectionPoolHelper.AcceptPooledConnection(IConnection connection, TimeoutHelper& timeoutHelper)
   at System.ServiceModel.Channels.ConnectionPoolHelper.EstablishConnection(TimeSpan timeout)
   at System.ServiceModel.Channels.ClientFramingDuplexSessionChannel.OnOpen(TimeSpan timeout)
   --- End of inner exception stack trace ---

Server stack trace: 
   at System.ServiceModel.Channels.ClientFramingDuplexSessionChannel.OnOpen(TimeSpan timeout)
   at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)
   at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)
   at System.ServiceModel.Channels.ServiceChannel.OnOpen(TimeSpan timeout)
   at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)

Exception rethrown at [0]: 
   at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
   at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
   at System.ServiceModel.ICommunicationObject.Open()
   at MEScontrol.Contracts.ChannelManager.TryToEsteblishChannel[TService](Boolean asyncPattern, ChannelParameters channelParameters, IAvailableServicesManager servicesManager, ServiceClientOptions options, IClientChannel& channel, Exception& error)
   at MEScontrol.Contracts.SyncClientProxyBase`1.GetSyncClient()
   at IDataCenterServiceProxy.Read(DataCenterConnectionItems[] )

我还注意到,当应用程序停止工作时,句柄数量稳步增长到一定限度。通常应用程序拥有大约750个句柄。当问题发生时,句柄数量增长到大约5800。 有时可能需要24小时才能达到极限,有时只需30分钟。我发现数字增长的句柄属于类型:线程和事件。

上次我设法进行多次应用程序转储,而句柄数量一直在增长。我用WinDbg检查了转储。我可以发现未启动(和待定)线程的数量正在增长。 Unstarted线程的数量很大。在最后一次转储中(当句柄号停止增长或即将停止时)我有953个未启动的线程。

同样奇怪的是,几乎所有'Threadpool worker'和'Threadpool Completion Port'线程似乎已经死了。除了ID为7的那个。

这些未开始的线程是什么意思以及为什么它们没有启动? 为什么线程池的线程已经死了? 我还能做些什么来找出应用程序停止工作的原因?

下面你会看到我在WinDbg中获得的结果,当句柄数量在增长时,其中一个转储正在进行中:

results of !threads

results of !eestack

results of !dumpheap -type System.Threading.Thread

托马斯更新:

0:000> !dlk
Examining SyncBlocks...
Scanning for ReaderWriterLock(Slim) instances...
Scanning for holders of ReaderWriterLock locks...
Scanning for holders of ReaderWriterLockSlim locks...
Examining CriticalSections...
No deadlocks detected.

更新

0:000> !threadpool
CPU utilization: 100%
Worker Thread: Total: 301 Running: 301 Idle: 0 MaxLimit: 1023 MinLimit: 1
Work Request in Queue: 4005
--------------------------------------
Number of Timers: 8
--------------------------------------
Completion Port Thread:Total: 6 Free: 0 MaxFree: 2 CurrentLimit: 6 MaxLimit: 1000 MinLimit: 1

0 个答案:

没有答案
相关问题