Подтвердить что ты не робот

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

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

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

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

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

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

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

4b9b3361

Ответ 1

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

Вы можете отключить предупреждение с помощью "Отладка + Исключения", откройте "Управляемые помощники отладки" node и отключите ContextSwitchDeadlock.

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

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