Веб-сервис C# застревает, ожидая блокировки, не возвращается

У нас есть C# (2.0) приложение, которое говорит с нашим сервером (в Java) через веб-сервисы.

В последнее время мы начали видеть следующее поведение в (ТОЛЬКО) одной из наших машин лаборатории (XP): Время от времени (каждые несколько дней), один из запроса к веб-сервису просто застрянет, не возвратится или тайм-аут.

Следующее является stacktrace, где это, кажется, застревает.

Разве никакая подсказка не имеет то, что продолжается здесь. Любой указатель очень помог бы.

ESP EIP
05eceeec 7c90eb94 [GCFrame: 05eceeec] 05ecefbc 7c90eb94 [HelperMethodFrame_1OBJ: 05ecefbc] Система. Поточная обработка. Монитор. Войдите (Система. Объект) система 05ecf014 7a5b0034. Сеть. ConnectionGroup. Разъедините (Система. Сеть. Соединение) система 05ecf040 7a5aeaa7. Сеть. Соединение. PrepareCloseConnectionSocket (Система. Сеть. ConnectionReturnResult ByRef) система 05ecf0a4 7a5ac0e1. Сеть. Соединение. ReadStartNextRequest (Система. Сеть. WebRequest, Система. Сеть. ConnectionReturnResult ByRef) система 05ecf0e8 7a5b1119. Сеть. ConnectStream. CallDone (Система. Сеть. ConnectionReturnResult) система 05ecf0fc 7a5b3b5a. Сеть. ConnectStream. ReadChunkedSync (Байт [], Int32, Int32) система 05ecf114 7a5b2b90. Сеть. ConnectStream. ReadWithoutValidation (Байт [], Int32, Int32, булевская переменная) система 05ecf160 7a5b29cc. Сеть. ConnectStream. Считайте (Байт [], Int32, Int32) систему 05ecf1a0 79473cab. IO.StreamReader. ReadBuffer (Символ [], Int32, Int32, булев ByRef) система 05ecf1c4 79473bd6. IO.StreamReader. Считайте (Символ [], Int32, Int32) систему 05ecf1e8 69c29119. Xml. XmlTextReaderImpl. ReadData () система 05ecf1f8 69c2ad70. Xml. XmlTextReaderImpl. ParseDocumentContent () система 05ecf20c 69c292d7. Xml. XmlTextReaderImpl. Считайте () систему 05ecf21c 69c2929d. Xml. XmlTextReader. Считайте () систему 05ecf220 6991b3e7. Сеть. Сервисы. Протоколы. SoapHttpClientProtocol. ReadResponse (Система. Сеть. Сервисы. Протоколы. SoapClientMessage, Система. Сеть. WebResponse, Система. IO.Stream, булевская переменная) система 05ecf268 69919ed1. Сеть. Сервисы. Протоколы. SoapHttpClientProtocol. Вызовите (Система. Строка, Система. Объект [])

Править:

После Ответа David я видел все потоки снова и нашел сообщника для мертвой блокировки:

ESP EIP
11a2f6f0 7c90eb94 [GCFrame: 11a2f6f0] 11a2f7c0 7c90eb94 [HelperMethodFrame_1OBJ: 11a2f7c0] Система. Поточная обработка. Монитор. Войдите (Система. Объект) 11a2f818 7a5ae107 Система. Сеть. Соединение. CloseOnIdle () 11a2f844 7a5b0403 Система. Сеть. ConnectionGroup. DisableKeepAliveOnConnections () 11a2f878 7a58c035 Система. Сеть. ServicePoint. ReleaseAllConnectionGroups () 11a2f8b4 7a58d40a Система. Сеть. ServicePointManager. IdleServicePointTimeoutCallback (Таймер, Int32, Система. Объект) 11a2f8e8 7a5d2f40 Система. Сеть. TimerThread+TimerNode. Огонь () 11a2f928 7a5d2bb2 Система. Сеть. TimerThread+TimerQueue. Огонь (Int32 ByRef) 11a2f968 7a5d2540 Система. Сеть. TimerThread. ThreadProc () 11a2f9b4 793d7a7b Система. Поточная обработка. ThreadHelper. ThreadStart_Context (Система. Объект) 11a2f9bc 793683dd Система. Поточная обработка. ExecutionContext. Выполненный (Система. Поточная обработка. ExecutionContext, Система. Поточная обработка. ContextCallback, Система. Объект) 11a2f9d4 793d7b5c Система. Поточная обработка. ThreadHelper. ThreadStart () 11a2fbf8 79e88f63 [GCFrame: 11a2fbf8]

Так, мы знаем, фиксируется ли это в 4,0?

1
задан blue 16 June 2010 в 17:58
поделиться

2 ответа

Это выглядит связанным... ошибка в CLR? Microsoft Connect

Edit: код во фреймворке 4.0 выглядит так, будто блокировки обрабатываются совершенно иначе. Возможно, там исправлена ошибка.

1
ответ дан 2 September 2019 в 23:45
поделиться

У вас почти наверняка возникла тупиковая ситуация. Предположим, у вас есть поток A, который снимает блокировку с объекта 2, а затем ждет, пока объект 1 будет разблокирован. Поток A вынужден ждать, потому что поток B снял блокировку с объекта 1, прежде чем разблокировать объект 2. Теперь и поток A, и поток B будут ждать вечно, потому что каждый из них ждет, пока другой что-то разблокирует.

Используйте отладчик для просмотра каждого потока в вашей программе и посмотрите, какие два потока сидят и ждут блокировки. Затем выясните, каких блокировок они ждут. Затем придумайте, как переписать программу так, чтобы эти две блокировки никогда не снимались в порядке, несовместимом для двух потоков.

Помните, что написание правильного кода блокировки требует глобального знания всех блокировок в программе, всех операций на всех потоках, которые могут их снять в любом возможном порядке. Вот почему так трудно сделать это правильно; большинство задач программирования требуют только локальных знаний. Замки требуют глобального знания всей программы, включая те части, которые вы не писали. Если какая-то сторонняя dll снимает блокировку с объекта, а ваш код ждет тот же объект, вы должны договориться с этим сторонним кодом о правильном выборе порядка блокировки.

Это наиболее вероятная причина. Существует маловероятная, но возможная другая причина, которая заключается в том, что иногда вы прерываете поток между моментом снятия блокировки и выполнением блока finally разблокировки. В C# 3 и ниже это приведет к тупику; мы исправили генератор кода в C# 4 так, чтобы этого больше не происходило. Однако мораль этой истории не в том, что "используйте C# 4", а в том, что "не прерывайте поток, никогда, и особенно не прерывайте поток, который может что-то заблокировать". Прерывание потока должно использоваться только в крайнем случае, когда вы все равно завершаете процесс.

1
ответ дан 2 September 2019 в 23:45
поделиться
Другие вопросы по тегам:

Похожие вопросы: