C#Web服务在等待锁定时被卡住,不会返回

C#Web服务在等待锁定时被卡住,不会返回,c#,web-services,.net-2.0,asmx,locking,C#,Web Services,.net 2.0,Asmx,Locking,我们有一个C#(2.0)应用程序,它通过web服务与我们的服务器(java)通信 最近,我们开始在(仅)一台实验室机器(XP)中看到以下行为: 每隔一段时间(每隔几天),其中一个Web服务请求就会被卡住,不会返回或超时 下面是stacktrace,它似乎被卡住了 我不知道这里发生了什么。 任何指针都会大有帮助 ESP EIP 05ECEEC 7c90eb94[GCFrame:05ECEEC] 05ecefbc 7c90eb94[帮助方法框架:05ecefbc] System.Threading.

我们有一个C#(2.0)应用程序,它通过web服务与我们的服务器(java)通信

最近,我们开始在(仅)一台实验室机器(XP)中看到以下行为: 每隔一段时间(每隔几天),其中一个Web服务请求就会被卡住,不会返回或超时

下面是stacktrace,它似乎被卡住了

我不知道这里发生了什么。 任何指针都会大有帮助

ESP EIP
05ECEEC 7c90eb94[GCFrame:05ECEEC] 05ecefbc 7c90eb94[帮助方法框架:05ecefbc] System.Threading.Monitor.Enter(System.Object) 05ecf014 7a5b0034 System.Net.ConnectionGroup.Disassociate(System.Net.Connection) 05ecf040 7a5aeaa7 System.Net.Connection.PrepareCloseConnectionSocket(System.Net.ConnectionReturnResult ByRef) 05ecf0a4 7a5ac0e1 System.Net.Connection.ReadStartNextRequest(System.Net.WebRequest, System.Net.ConnectionReturnResult(ByRef) 05ecf0e8 7a5b1119 System.Net.ConnectStream.CallDone(System.Net.ConnectionReturnResult) 05ecf0fc 7a5b3b5a System.Net.ConnectStream.ReadChunkedSync(字节[],Int32, Int32) 05ecf114 7a5b2b90 System.Net.ConnectStream.ReadWithoutValidation(字节[],Int32, Int32,布尔值) 05ecf160 7a5b29cc System.Net.ConnectStream.Read(字节[],Int32,Int32) 05ecf1a0 79473cab System.IO.StreamReader.ReadBuffer(Char[],Int32,Int32, 布尔(ByRef) 05ecf1c4 79473bd6 System.IO.StreamReader.Read(Char[],Int32,Int32) 05ecf1e8 69c29119 System.Xml.XmlTextReaderImpl.ReadData() 05ecf1f8 69c2ad70 System.Xml.XmlTextReaderImpl.ParseDocumentContent()文件 05ecf20c 69c292d7 System.Xml.XmlTextReaderImpl.Read() 05ecf21c 69c2929d System.Xml.XmlTextReader.Read() 05ecf220 6991b3e7 System.Web.Services.Protocols.SoapHttpClientProtocol.ReadResponse(System.Web.Services.Protocols.SoapClientMessage, System.Net.WebResponse,System.IO.Stream,布尔值) 05ecf268 69919ed1 System.Web.Services.Protocols.SoapHttpClientProtocol.Invoke(System.String, 系统对象[])

编辑:

在David回答之后,我再次查看了所有线程,并找到了死锁的同谋:

ESP EIP
11a2f6f0 7c90eb94[GCFrame:11a2f6f0] 11a2f7c0 7c90eb94[HelperMethodFrame\u 1OBJ:11a2f7c0]系统.线程.监视器.输入(系统.对象) 11a2f818 7a5ae107系统.Net.Connection.CloseOnIdle() 11a2f844 7a5b0403 System.Net.ConnectionGroup.DisableKeepAliveOnConnections() 11a2f878 7a58c035 System.Net.ServicePoint.ReleaseAllConnectionGroups() 11a2f8b4 7a58d40a System.Net.ServicePointManager.IdleServicePointTimeoutCallback(计时器、Int32、System.Object) 11a2f8e8 7a5d2f40系统.Net.timerRead+TimerNode.Fire() 11a2f928 7a5d2bb2 System.Net.TimerRead+TimerQueue.Fire(Int32 ByRef) 11a2f968 7a5d2540 System.Net.TimerThread.ThreadProc() 11a2f9b4 793d7a7b System.Threading.ThreadHelper.ThreadStart\u上下文(System.Object) 11a2f9bc 793683dd System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext,System.Threading.ContextCallback,System.Object) 11a2f9d4 793d7b5c System.Threading.ThreadHelper.ThreadStart() 11a2fbf8 79e88f63[GCFrame:11a2fbf8]


那么,我们知道它是否在4.0中被修复了吗?

这看起来与。。。CLR中的bug?


编辑:4.0框架中的代码看起来锁的处理方式完全不同。它可能已经修复了错误。

您几乎肯定会遇到死锁。假设您有一个线程,它取出对象2上的锁,然后等待对象1解锁。线程A必须等待,因为线程B在解锁对象2之前已经解除了对象1上的锁定。现在线程A和线程B都将永远等待,因为每个线程都在等待另一个线程解锁某些东西

使用调试器查看程序中的每个线程,并查看哪两个线程都在那里等待锁定。然后找出他们正在等待的锁。然后找出如何重写程序,使这两个锁在两个线程上不会以不一致的顺序取出

请记住,编写正确的锁定代码需要全面了解程序中的所有锁,以及所有线程上的所有操作,这些操作可能会以各种可能的顺序将它们取出。这就是为什么很难做到正确;大多数编程任务只需要本地知识。锁需要整个程序的全局知识,包括您没有编写的部分。如果某个第三方dll正在解除对象上的锁,而您的代码正在等待同一个对象,那么您必须同意该第三方代码关于正确的锁顺序选择


这是最有可能的原因。还有一个不太可能但可能的其他原因,那就是有时在取出锁和执行最终解锁块之间中止线程。这将导致C#3及以下版本出现死锁;我们已经在C#4中修复了代码生成器,这样就不会再发生这种情况。这个故事的寓意不是“使用C#4”,而是“永远不要中止线程,尤其是不要中止可能锁定某个对象的线程”。线程中止只能在关闭进程时作为最后手段使用。

您说“C#2.0”,但也可以在.NET 3.5中使用C#2.0。我猜你的意思是你在使用.NET2.0?很抱歉没有清楚地提到这一点。是的,它是.NET 2.0Eric,如果你跟踪堆栈跟踪,他不会带锁。NET CLR代码正在执行此操作。我对2.0和4.0组件使用了reflector,并且锁定策略非常不同。我假设这是一个可能的2.0错误的修复。但是我找不到关于这个bug的官方通知。