.NET应用程序为什么会停止执行任何网络I/O?

问题描述:

我正在调查客户端工作站上出现的问题,其中一个相当大的WinForms .NET 3.5应用程序偶尔会停止执行任何类型的网络操作,并且最终会由于主要执行的网络操作而冻结线。.NET应用程序为什么会停止执行任何网络I/O?

通过网络操作,我的意思是任何需要新的网络连接。该应用程序连接到多个Oracle数据库和SOAP Web服务。

检查该应用程序的存储器转储示出了各种阻塞的呼叫到在不同的线程非托管代码:

DNS查找卡住(System.Net.UnsafeNclNativeMethods+SafeNetHandlesXPOrLater.getaddrinfo

Open套接字卡住卡住(System.Net.UnsafeNclNativeMethods+OSSOCK.WSAConnect

关闭套接字( System.Net.UnsafeNclNativeMethods+SafeNetHandles.closesocket

打开ODBC卡(System.Data.Common.UnsafeNativeMethods.SQLDriverConnectW

上述所有看起来像这样的非托管堆的顶部:

0a90df4c 77858cd8 ntdll!ZwWaitForSingleObject+0x15 
0a90df74 73c5716f ntdll!RtlIntegerToUnicodeString+0x20b 
0a90dfbc 76f45db1 siifslsp!WSPStartup+0x483f 

重新启动应用程序后,恢复正常。这向我暗示了某种类型的资源泄漏,但是我怎样才能追踪到这一点?

我检查打开的网络连接的情况下,可以看到下面的罪状:

  • System.Net.HttpWebRequest 5个实例
  • System.Net.Sockets.Socket 11实例
  • System.Data.Odbc.OdbcConnectionHandle 4个实例

这些不对我来说看起来异常高。

更新1 - !FinalizeQueue

输出的!FinalizeQueue的输出被截断并不显示任何异常情况给我。我已经限制它与任何IO相关。

0:024> !FinalizeQueue 
SyncBlocks to be cleaned up: 0 
MTA Interfaces to be released: 0 
STA Interfaces to be released: 0 
---------------------------------- 
generation 0 has 359 finalizable objects (41f35654->41f35bf0) 
generation 1 has 0 finalizable objects (41f35654->41f35654) 
generation 2 has 10697 finalizable objects (41f2af30->41f35654) 
Ready for finalization 0 objects (41f35bf0->41f35bf0) 
Statistics: 
     MT Count TotalSize Class Name 
6e612a38  1   20 System.Net.SafeLocalFree 
6ea7e550  1   24 System.Net.Sockets.TcpClient 
6a606c54  1   24 System.Data.Odbc.OdbcEnvironmentHandle 
6e60f7f4  2   40 System.Net.SafeFreeAddrInfo 
05da845c  2   40 System.Net.SafeCloseSocket+InnerSafeCloseSocket 
0642c010  2   56 System.Net.SafeCloseSocketAndEvent 
6e6106bc  4   96 System.Net.SafeRegistryHandle 
6e6105d0  4   112 System.Net.SafeCloseSocketAndEvent 
6a6069bc  4   112 System.Data.Odbc.OdbcConnectionHandle 
6a6060c8  4   256 System.Data.Odbc.OdbcConnection 
6e60f764  11   264 System.Net.SafeCloseSocket 
6e6115cc  7   336 System.Net.Sockets.NetworkStream 
66e60eeec  11   836 System.Net.Sockets.Socket 

Total 11056 objects 

更新2 - 使用!locks!critsec看看那里的块

!critsec输出是:

0:002> !critsec 73c7147c 

CritSec siifslsp!GetLspGuid+1a0fc at 73c7147c 
WaiterWoken  No 
LockCount   8 
RecursionCount  1 
OwningThread  5f24 
EntryCount   0 
ContentionCount 8 
*** Locked 

不知道5f24指的是什么。 !Threads的输出没有显示任何线程,其的5f24

我承认我没有明确的答案,但这里有一些建议。

首先,尝试通过在WinDbg中使用!waitlist命令来解决线程阻塞的问题,如this blog post中所述。这可能会引发一些线索,这可以解释为什么不同的线程被阻塞。

Here's another handy blog post它解释了如何深入挖掘什么阻塞线程。

好信息的另一个来源可能是Event Viewer,特别是the Windows Logs -> System部分。你可以在这里扫描条目,并寻找任何ErrorWarnings,看看他们说什么。可能有网络相关的消息张贴在那里,你永远不知道。

我会不断更新这个答案,因为我发现了其他可能对您有用的信息。

+0

的siifslsp是与卸载应用程序相关联的一个Winsock LSP。删除WinSock LSP解决了问题。 – Iain 2013-03-14 15:00:42

+0

@Iain很高兴你解决了这个问题。我的答案是否帮助你,我不确定什么是WinSock LSP,以及你是如何发现它与卸载的应用程序相关联的。听起来很深:) – 2013-03-14 15:15:46

+0

这是一个很长的故事,但你的回答激励我深入探究非托管代码。从我的回答中的更新2开始,我使用命令'lmv m siifslsp'来识别siifslsp DLL,并且一些Google使用告诉我'GetLspGuid'方法是您在WinSock LSP上找到的东西。我得到了DLL并在记事本中打开它来搜索任何可能暗示它是源的字符串。我发现供应商并最终追踪了它所属的软件,用户认为该软件是他最近从他的机器上移除的,因为这是他的问题。案件结案。 – Iain 2013-03-14 16:06:55

.NET将默认将远程连接数限制为2。

确保以下属性被正确设定:

<system.net> 
    <connectionManagement> 
    <add address = "*" maxconnection = "24" /> 
    </connectionManagement> 
</system.net> 

看进一步的信息,下面的MSDN页:

http://msdn.microsoft.com/en-gb/library/system.net.configuration.connectionmanagementelement.maxconnection(v=vs.100).aspx