为什么.NET应用程序无法执行任何网络I / O?

时间:2013-03-12 20:40:30

标签: .net winsock

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

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

检查应用程序的内存转储会显示对不同线程上的非托管代码的各种阻止调用:

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

打开套接字卡住(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的输出未显示任何OSID 5f24的帖子。

2 个答案:

答案 0 :(得分:1)

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

首先,按照this blog post中的说明,尝试使用WinDbg中的!waitlist命令计算线程阻塞的内容。这可能会提供一个线索,可以解释为什么不同的线程阻塞。

Here's another handy blog post解释了如何深入挖掘阻止线程的内容。

良好信息的另一个来源可能是Event Viewer,特别是the Windows Logs -> System部分。您可以在此处扫描条目并查找任何ErrorWarnings并查看他们所说的内容。可能会在那里发布与网络相关的消息,你永远不会知道。

我将继续更新此答案,因为我找到了其他可能有用的信息。

答案 1 :(得分:0)

.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