.NET - обнаружен ContextSwitchDeadlock
У меня есть класс в C# (.net 3.5 cp, vs2010), который выполняет сложные вычисления, которые обычно занимают много времени. Через минуту выдается исключение, что ContextSwitchDeadlock был обнаружен. Исключение локализовано, для моего не английского языка, поэтому я не могу скопировать вставить, но смысл следующий: following Модуль CLR не мог перейти из контекста COM ... в контекст COM ... в течение 60 секунд. Подпроцессы, которые владеют целевым контекстом / квартирой, вероятно, не ожидают перекачки или обрабатывают очень долгую операцию без перекачки системных сообщений Windows.
По сути, похоже, что мое приложение работает на компьютере и долгое время не отвечает на запросы Windows, а Visual Studio закрывает его и сообщает о возможном тупике.
Я пытался провести некоторое исследование и нашел два решения:
Отключите некоторые опции в визуальном отладчике студии для обнаружения тупиков. Не работает для меня, потому что это работает только для целей отладки.
Вызвать некоторый метод DoEvents, но это было для форм Windows, а не WPF, и я использую WPF.
Было также предложение создать отдельную тему, но я совершенно не знаком с темами и не знаю, что мне делать. Любые предложения, пожалуйста?
1 ответ
Это всего лишь предупреждение от Managed Debugging Assistant (MDA). Ваш код нарушает довольно жесткое требование к потокам Single Threaded Apartment (STA), они не могут блокироваться в течение длительного времени. Предупреждение достаточно реально, блокировка потока пользовательского интерфейса может легко вызвать взаимоблокировку. Но объяснение в вашем случае простое, оно становится просто кататоническим, потому что занята вычислениями, а не потому, что оно фактически заблокировано. MDA не может отличить.
Вы можете отключить предупреждение с помощью Debug + Exceptions, открыть узел Managed Debugging Assistants и снять флажок ContextSwitchDeadlock.
Это по-прежнему оставляет пользователю окно на рабочем столе, которое мертво для мира, что не очень удобно для пользователя. И это может иметь побочные эффекты, в результате чего другие программы перестают отвечать на запросы при отправке сообщений в окна верхнего уровня.
Вам действительно нужно использовать многопоточность, чтобы действительно решить эту проблему. Взгляните на BackgroundWorker, он хорошо документирован в библиотеке MSDN и во многих других местах.