.NET - обнаружен ContextSwitchDeadlock

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

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

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

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

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

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

1 ответ

Решение

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

Вы можете отключить предупреждение с помощью Debug + Exceptions, открыть узел Managed Debugging Assistants и снять флажок ContextSwitchDeadlock.

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

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

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