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

为什么.NET应用程序不能执行任何网络I/O?,.net,winsock,.net,Winsock,我正在调查一个客户端工作站上出现的问题,其中一个相当大的WinForms.NET 3.5应用程序偶尔会停止执行任何类型的网络操作,并最终由于在主线程上执行网络操作而冻结 所谓网络操作,我指的是任何需要新网络连接的东西。该应用程序连接到多个Oracle数据库和SOAP web服务 检查应用程序的内存转储会显示对不同线程上非托管代码的各种阻止调用: DNS查找被卡住(System.Net.UnsafeNclNativeMethods+SafeNetHandlesXPOrLater.getaddrin

我正在调查一个客户端工作站上出现的问题,其中一个相当大的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.unsafentivemethods.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-截断
的输出!最终确定EQUEUE

的输出!FinalizeEQUEUE
对我来说没有任何异常。我把它限制在与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-使用
!锁定
!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
指的是什么。
的输出!线程
没有显示任何OSID为
5f24
的线程,我承认我没有明确的答案,但这里有一些建议

首先,尝试使用
找出线程阻塞的对象!WinDbg中的waitlist
命令,如中所述。这可能会提供一条线索,解释为什么不同的线程会阻塞

这解释了如何更深入地挖掘,以找到阻止线程的原因

另一个好的信息来源可能是
事件查看器
,特别是
Windows日志->系统
部分。您可以扫描此处的条目,查找任何
错误
警告
,并查看它们的内容。你永远也不知道,那里可能有与网络相关的消息


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

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

首先,尝试使用
找出线程阻塞的对象!WinDbg中的waitlist
命令,如中所述。这可能会提供一条线索,解释为什么不同的线程会阻塞

这解释了如何更深入地挖掘,以找到阻止线程的原因

另一个好的信息来源可能是
事件查看器
,特别是
Windows日志->系统
部分。您可以扫描此处的条目,查找任何
错误
警告
,并查看它们的内容。你永远也不知道,那里可能有与网络相关的消息


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

.NET将默认情况下将远程连接数限制为2

确保正确设置了以下属性:

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


.NET默认情况下将远程连接数限制为2

确保正确设置了以下属性:

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


siifslsp是与卸载的应用程序关联的WinSock LSP。删除WinSock LSP解决了问题。@Iain很高兴您解决了问题。我的回答对您有帮助吗?我不确定WinSock LSP是什么,以及您是如何发现它与已卸载的应用程序关联的。听起来很深奥:)说来话长,但你的回答启发我深入研究非托管代码。从更新2开始,在我的回答中,我使用命令
lmv m siifslsp
来识别
siifslsp
DLL,一些谷歌用户告诉我,在WinSock LSP上可以找到“GetLspGuid”方法。我得到了DLL,并在记事本中打开它来搜索任何可能暗示其来源的字符串。我找到了供应商,并最终找到了该软件的一部分,用户认出该软件是他最近从机器上删除的,因为它给他带来了问题。案件结案。我真的不知道LSP的细节,但我回忆起几年前在机器上遇到的问题,损坏的WinSock堆栈会阻止联网的发生。通常,由于应用程序已将自己的不可靠插件(LSP?)插入WinSock堆栈,因此siifslsp是与已卸载应用程序关联的WinSock LSP。删除WinSock LSP解决了问题。@Iain很高兴您解决了问题。我的回答对您有帮助吗?我不确定WinSock LSP是什么,以及您是如何发现它与已卸载的应用程序关联的。听起来很深奥:)说来话长,但你的回答启发我深入研究非托管代码。从更新2开始,在我的回答中,我使用命令
lmv m siifslsp
来识别
siifslsp
DLL,一些谷歌用户告诉我,在WinSock LSP上可以找到“GetLspGuid”方法。我得到了DLL,并在记事本中打开它来搜索任何可能暗示其来源的字符串。我找到了供应商,并最终找到了它所属的软件