2010-06-15 11 views
1

Nous avons une application C# (2.0) qui parle à notre serveur (en Java) via les services Web. Dernièrement, nous avons commencé à voir le comportement suivant dans (SEULEMENT) l'une de nos machines de laboratoire (XP): De temps en temps (tous les quelques jours), une demande de service Web va juste rester bloquée, ne retournera pas ou ne dépassera pas .Le service Web C# se bloque en attente de verrouillage, ne renvoie pas

Voici la pile où elle semble être bloquée.

N'avez aucune idée de ce qui se passe ici. Tout pointeur serait d'une grande aide.

ESP EIP
05eceeec 7c90eb94 [GCFrame: 05eceeec] 05ecefbc 7c90eb94 [HelperMethodFrame_1OBJ: 05ecefbc] System.Threading.Monitor.Enter (System.Object) 05ecf014 7a5b0034 System.Net.ConnectionGroup.Disassociate (système. 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) 05e cf0e8 7a5b1119 System.Net.ConnectStream.CallDone (System.Net.ConnectionReturnResult) 05ecf0fc 7a5b3b5a System.Net.ConnectStream.ReadChunkedSync (byte [], Int32, Int32) 05ecf114 7a5b2b90 System.Net.ConnectStream.ReadWithoutValidation (Byte [ ], Int32, Int32, Boolean) 05ecf160 7a5b29cc System.Net.ConnectStream.Read (byte [], Int32, Int32) 05ecf1a0 79473cab System.IO.StreamReader.ReadBuffer (Char [], Int32, Int32, booléenne 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, Boolean) 05ecf268 69919ed1 System.Web.Services.Protocols.SoapHttpClientProtocol.Invoke (System.String, System.Object [])

Edit:

Après la réponse de David, j'ai revu tous les fils et j'ai trouvé l'acco mplice du blocage:

ESP EIP
11a2f6f0 7c90eb94 [GCFrame: 11a2f6f0] 11a2f7c0 7c90eb94 [HelperMethodFrame_1OBJ: 11a2f7c0] System.Threading.Monitor.Enter (System.Object) 11a2f818 7a5ae107 System.Net.Connection.CloseOnIdle() 11a2f844 7a5b0403 System.Net.ConnectionGroup.DisableKeepAliveOnConnections() 11a2f878 7a58c035 System.Net.ServicePoint.ReleaseAllConnectionGroups() 11a2f8b4 7a58d40a System.Net.ServicePointManager.IdleServicePointTimeoutCallback (minuterie, Int32, System.Object) 11a2f8e8 7a5d2f40 système. Net.TimerThread + TimerNode.Fire() 11a2f928 7a5d2bb2 System.Net.TimerThread + TimerQueue.Feu (Int32 ByRef) 11a2f968 7a5d2540 System.Net.TimerThread.ThreadProc() 11a2f9b4 793d7a7b System.Threading.ThreadHelper.ThreadStart_Context (System.Object) 11a2f9bc 793683dd System.Threading.ExecutionContext.Run (System.Threading.ExecutionContext, système .Threading.ContextCallback, System.Object) 11a2f9d4 793d7b5c System.Threading.ThreadHelper.ThreadStart() 11a2fbf8 79e88f63 [GCFrame: 11a2fbf8]

Alors, pouvons-nous savoir si elle est fixée à 4,0?

+0

Vous dites "C# 2.0", mais il est possible d'utiliser C# 2.0 avec .NET 3.5. Je présume que vous voulez dire que vous utilisez .NET 2.0? –

+0

Désolé de ne pas le mentionner clairement. oui c'est. NET 2.0 – blue

Répondre

1

Cela semble lié ... bug dans CLR? Microsoft Connect

Modifier: le code dans le cadre 4.0 ressemble serrures sont traitées de façon totalement différente. Cela a peut-être corrigé le bug.

+0

Merci David pour le signaler !! – blue

1

Vous avez presque certainement un blocage. Supposons que vous ayez un thread A qui retire le verrou de l'objet 2 et attend que l'objet 1 soit déverrouillé. Le thread A doit attendre parce que le thread B a retiré le verrou sur l'objet 1 avant de déverrouiller l'objet 2. Maintenant, le thread A et le thread B attendent tous les deux car chacun attend l'autre pour débloquer quelque chose. Utilisez le débogueur pour examiner chaque thread de votre programme et voir les deux threads qui sont assis là en attente d'un verrou. Ensuite, déterminez les verrous qu'ils attendent. Ensuite, déterminez comment réécrire votre programme afin que ces deux verrous ne soient jamais supprimés dans un ordre incohérent sur deux threads. Rappelez-vous, l'écriture correcte du code de verrouillage nécessite connaissance globale de tous les verrous du programme, toutes les opérations sur tous les threads qui pourraient éventuellement les sortir dans tous les ordres possibles. C'est pourquoi c'est si difficile de bien faire les choses; la plupart des tâches de programmation nécessitent uniquement des connaissances locales. Les serrures exigent une connaissance globale de l'ensemble du programme, , y compris les parties que vous n'avez pas écrites. Si une DLL tierce retire un verrou sur un objet et que votre code est en attente sur le même objet, vous devez accepter ce code tiers sur le choix de l'ordre de verrouillage correct.

C'est la cause la plus probable. Il y a une autre cause, improbable mais possible, à savoir que parfois, vous annulez un thread entre le moment où le verrou est retiré et celui où le bloc de déverrouillage est finalement exécuté. Cela entraînera un blocage dans C# 3 et ci-dessous; nous avons corrigé le générateur de code en C# 4 pour que cela ne se produise plus. La morale de l'histoire ici n'est cependant pas "d'utiliser C# 4", c'est "n'abandonne pas un fil, jamais, et surtout n'abandonne pas un fil qui pourrait se bloquer sur quelque chose". Les interruptions de fil ne doivent être utilisées qu'en dernier recours, quand vous enlevez le processus de toute façon.

+0

Eric, si vous suivez la trace de la pile, il ne prend pas de verrou. Le code .NET CLR le fait. J'ai utilisé un réflecteur contre les assemblages 2.0 et 4.0, et la stratégie de verrouillage est très différente. Je suppose que c'était un correctif de bogue pour un bug 2.0 possible. Je n'ai pas pu trouver un avis ** officiel ** du bug. –