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