Что может вызвать / как я могу предотвратить ContextSwitchDeadlock?

У меня довольно длительный процесс в службе Windows, который периодически выдает исключение "ContextSwitchDeadlock":

Я также настроил свой сервис для отправки себе электронных писем с подробностями о возникших исключениях. Я получил:

Date: 05/25/2016 09:16:32:
Exception message: Timeout expired.  The timeout period elapsed prior to completion of the operation or the server is not responding.
Exception Source: .Net SqlClient Data Provider

... а затем через три секунды это:

Date: 05/25/2016 09:16:35: 
Exception message: Cannot find table 0.
Exception Source: System.Data

КСТАТИ: По крайней мере, это соответствует: у меня было три пары этих исключений, и каждый раз вторая датируется точно через три секунды после первой.

У меня был предыдущий опыт с имитацией значения CommandTimeout SQLCommand (в настоящее время установлено на 360) тем или иным способом, и это похоже на метание дротиков с завязанными глазами или даже черную магию. Есть ли лучший способ предотвратить такие тупики?

У меня есть другие очень похожие методы, которые не вызывают эту проблему; те занимают меньше времени. Продолжительность метода (в частности, время, необходимое для выполнения запроса), кажется, "загвоздка". Я не могу изменить это - "это то, что есть" - так что еще я могу сделать?

ОБНОВИТЬ

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

1 ответ

Решение

ContextSwitchDeadlock является "помощником по управляемой отладке" в Visual Studio и является одним из многих инструментов, которые отладчик Visual Studio предоставляет вам дополнительную помощь при отладке приложения.

Я не уверен на 100%, какую эвристику он использует, чтобы выяснить, когда вызывать, но я знаю кое-что, и это также описано в самом окне инструмента:

Текущий поток в данный момент не выполняет код или стек вызовов не может быть получен.

Эта последняя часть - это то, что обычно отключает Visual Studio, и это обычно происходит, когда управляемая (.NET) программа вызывает COM или P/Invoke. Когда это будет сделано, Visual Studio больше не сможет смотреть на программу и выяснить, что она делает, а когда это займет более 60 секунд, она обнаружит, что что-то пошло не так.

Если ваша программа выполняет вышеуказанное, вызывает COM, использует P / Invoke или что-то, связанное с внешним неуправляемым (.NET) кодом, и выполнение этого внешнего кода занимает более 60 секунд, тогда диалог в основном ложно положительный. Если вы знаете, что это доброкачественно, например, "да, он вызывает внешний код, и да, иногда это может занять более 60 секунд", тогда вы можете снять флажок ниже на этом изображении:

[] Прерывание при возникновении этого типа исключения

Обратите внимание, что это не обязательно исключение, это скорее Visual Studio, просто поднимающий красный флаг при подозрительном (для него) поведении. Если вы знаете, что все в порядке, просто скажите, чтобы он прекратил поднимать этот флаг.

Обратите внимание, что это не имеет ничего общего с другими реальными исключениями, которые вы упомянули в вопросе, а только с большим диалогом ContextSwitchDeadlock.

Другие вопросы по тегам