1

我正在调查在客户端工作站上看到的一个问题,其中相当大的 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.HttpWebRequest5 个实例
  • System.Net.Sockets.Socket11 个实例
  • System.Data.Odbc.OdbcConnectionHandle4 个实例

这些对我来说看起来并不高。

更新 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不显示任何带有OSIDof 的线程5f24

4

2 回答 2

1

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

!waitlist首先,尝试使用WinDbg 中的命令找出线程阻塞的对象,如本博文中所述。这可能会抛出一个线索,可以解释为什么不同的线程被阻塞。

这是另一个方便的博客文章,它解释了如何深入挖掘以找到阻塞线程的内容。

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

我会不断更新此答案,因为我会为您找到其他可能有用的信息。

于 2013-03-12T20:48:06.003 回答
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

于 2013-03-14T11:20:09.657 回答