.NET - обнаружен ContextSwitchDeadlock - PullRequest
17 голосов
/ 12 ноября 2011

У меня есть класс в c # (.net 3.5 cp, vs2010), который выполняет сложные вычисления, которые обычно занимают много времени.Через минуту выдается исключение, что ContextSwitchDeadlock был обнаружен.Исключение локализовано, для моего не английского языка, поэтому я не могу скопировать вставить, но смысл следующий: following Модуль CLR не мог перейти из контекста COM ... в контекст COM ... в течение 60 секунд.Подпроцессы, которые владеют целевым контекстом / квартирой, вероятно, не ожидают перекачки или обрабатывают очень длительную операцию без перекачки системных сообщений Windows.

По сути, похоже, что мое приложение вычисляет и долго не отвечает на окна, а Visual Studio отключает его и сообщает о вероятном тупике.

Я пытался провести какое-то исследование и нашелдва решения:

  1. Отключить некоторые опции в отладчике Visual Studio для обнаружения взаимоблокировок.Не работает для меня, потому что это работает только для целей отладки.

  2. Вызовите некоторый метод DoEvents, но это было для оконных форм, а не WPF, и я использую WPF.

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

1 Ответ

40 голосов
/ 12 ноября 2011

Это всего лишь предупреждение от Managed Debugging Assistant (MDA). Ваш код нарушает довольно жесткое требование к потокам Single Threaded Apartment (STA), они не могут блокироваться в течение длительного времени. Предупреждение является вполне реальным, блокировка потока пользовательского интерфейса может легко вызвать взаимоблокировку. Но объяснение в вашем случае простое, оно становится просто кататоническим, потому что занята вычислениями, а не потому, что оно фактически заблокировано. MDA не может отличить.

Вы можете отключить предупреждение с помощью «Отладка + Исключения», открыть узел «Помощники по управляемой отладке» и снять флажок ContextSwitchDeadlock.

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

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

...