Visual Studio: ContextSwitchDeadlock
У меня появилось сообщение об ошибке, которое я не могу решить. Это происходит из Visual Studio или отладчика. Я не уверен, является ли конечное условие ошибки в VS, отладчике, моей программе или базе данных.
Это приложение для Windows. Не веб-приложение.
Первое сообщение от VS - это всплывающее окно, в котором говорится:
"Никакие символы не загружаются для любого стека стека вызовов. Исходный код не может быть отображен".
Когда это будет нажато, я получаю:
" ContextSwitchDeadlock был обнаружен" вместе с длинным сообщением, воспроизводимым ниже.
Ошибка возникает в цикле, который сканирует DataTable. Для каждой строки он использует значение ключа (HIС#) из таблицы в качестве параметра для SqlCommand. Команда используется для создания SqlDataReader, который возвращает одну строку. Данные сравниваются. Если обнаружена ошибка, строка добавляется ко второй DataTable.
Похоже, что ошибка связана с тем, сколько времени требуется для выполнения процедуры (т.е. через 60 секунд), а не с количеством ошибок. Я не думаю, что это проблема памяти. Внутри цикла не объявляются переменные. Единственными созданными объектами являются SqlDataReaders, и они находятся в разделе "Использование структур". Добавить System.GC.Collect() не имеет эффекта.
db - это сайт SqlServer на том же ноутбуке.
В Форме нет причудливых штучек или гаджетов.
Я не знаю ничего в этом процессе, который сильно отличается от того, что я делал десятки раз. Я видел ошибку раньше, но никогда не на постоянной основе.
Любые идеи, кто-нибудь?
Полная ошибка Текст:
CLR не смог перейти из контекста COM 0x1a0b88 в контекст COM 0x1a0cf8 в течение 60 секунд. Поток, который владеет целевым контекстом/квартирой, скорее всего, либо выполняет ненакачивание, либо обрабатывает очень длительную операцию без перекачки сообщений Windows. Эта ситуация, как правило, имеет отрицательное влияние на производительность и может даже привести к тому, что приложение становится неактивным или память автоматически накапливается с течением времени. Чтобы избежать этой проблемы, все потоки с одной резьбой (STA) должны использовать примитивы ожидания накачки (например, CoWaitForMultipleHandles) и регулярно накачать сообщения во время длительных операций.
Ответы
Ответ 1
ContextSwitchDeadlock
не обязательно означает, что у вашего кода есть проблема, просто есть потенциал. Если вы перейдете в Debug > Exceptions
в меню и разверните Managed Debugging Assistants
, вы найдете ContextSwitchDeadlock
включен. Если вы отключите это, VS больше не будет предупреждать вас, когда элементы занимают много времени для обработки. В некоторых случаях вы можете иметь длительную операцию. Это также полезно, если вы отлаживаете и останавливаетесь на линии, пока это обрабатывается, - вы не хотите, чтобы она жаловалась, прежде чем у вас была возможность разобраться в проблеме.
Ответ 2
Как сказал Педро, у вас есть проблема с отладчиком, предотвращающим передачу сообщений, если вы переходите через код.
Но если вы выполняете длительную операцию в потоке пользовательского интерфейса, вызовите Application.DoEvents(), который явно перенаправляет очередь сообщений, а затем возвращает управление вашему текущему методу.
Однако, если вы это делаете, я бы порекомендовал вам взглянуть на ваш дизайн, чтобы вы могли выполнять обработку с потока пользовательского интерфейса, чтобы ваш пользовательский интерфейс оставался приятным и быстрым.
Ответ 3
Похоже, вы делаете это в основном потоке пользовательского интерфейса в приложении. Поток пользовательского интерфейса отвечает за пересылку оконных сообщений по мере поступления, и все же, поскольку ваш заблокирован в вызовах базы данных, он не может этого сделать. Это может вызвать проблемы с сообщениями системы.
Вы должны посмотреть, как создать фоновый поток для продолжительной работы и развернуть какой-то диалог "Я занят" для пользователя, когда это произойдет.
Ответ 4
Если вы не хотите отключать это исключение, все, что вам нужно сделать, это позволить вашему приложению передавать сообщения хотя бы раз в 60 секунд. Это предотвратит это исключение.
Попробуйте вызвать System.Threading.Thread.CurrentThread.Join(10) раз в то время. Существуют другие вызовы, которые вы можете сделать, чтобы сообщения отображались.
Ответ 5
Вышеупомянутое решение хорошо в некоторых сценариях, но есть другой сценарий, когда это происходит, когда вы тестируете устройство, и вы пытаетесь "Отлаживать выбранные тесты" из тестового проводника, когда решение не настроено на "Отладка".
В этом случае вам нужно изменить свое решение на Release или на то, что он настроен на Debug в этом случае. Если это проблема, то изменение "ContextSwitchDeadlock" на самом деле вам не поможет.
Я пропустил это сам, потому что сообщение об ошибке было настолько противным, что я не проверял очевидную вещь, которая была настройкой Debug!
Ответ 6
В испанской версии Visual Studio 2017.
"Depurar" → "Ventanas" → "Конфигурация de Excepciones"
и выполните поиск "ContextSwitchDeadlock".
Затем снимите флажок.
Или ярлык
CTRL + D, Е
Бест.
Ответ 7
Вы можете решить эту проблему, сняв флажок contextswitchdeadlock с
Отладка- > Исключения... → Развернуть MDA node → снимите флажок → контекстный переключатель