Visual Studio: ContextSwitchDeadlock

167

Я получаю сообщение об ошибке, которое не могу устранить. Это происходит из Visual Studio или отладчика. Я не уверен, является ли окончательное состояние ошибки в VS, отладчике, моей программе или базе данных.

Это приложение для Windows. Не веб-приложение.

Первое сообщение от VS - это всплывающее окно, в котором говорится: «Ни для одного кадра стека вызовов не загружены символы. Исходный код не может быть отображен». Когда это щелкают, я получаю: « ContextSwitchDeadlock был обнаружен », наряду с длинным сообщением, воспроизведенным ниже.

Ошибка возникает в цикле, который просматривает DataTable. Для каждой строки он использует значение ключа (HIC #) из таблицы в качестве параметра для SqlCommand. Команда используется для создания SqlDataReader, который возвращает одну строку. Данные сравниваются. Если обнаружена ошибка, строка добавляется во второй DataTable.

Ошибка, по-видимому, связана с тем, сколько времени занимает процедура (т. Е. Через 60 секунд), а не с тем, сколько ошибок найдено. Я не думаю, что это проблема памяти. В цикле не объявляются переменные. Единственными объектами, которые создаются, являются SqlDataReaders, и они находятся в структуре Using. Добавление System.GC.Collect () не дало эффекта.

БД - это сайт SqlServer на том же ноутбуке.

Там нет никаких причудливых вещиц или гаджетов в форме.

Я не знаю ничего в этом процессе, что сильно отличается от того, что я делал десятки раз раньше. Я видел ошибку раньше, но никогда не на постоянной основе.

Любые идеи, кто-нибудь?

Полная ошибка Текст: CLR не удалось перейти из контекста COM 0x1a0b88 в контекст COM 0x1a0cf8 в течение 60 секунд. Поток, который владеет целевым контекстом / квартирой, скорее всего либо выполняет некачивающее ожидание, либо обрабатывает очень длительную операцию без прокачки сообщений Windows. Эта ситуация, как правило, оказывает негативное влияние на производительность и может даже привести к тому, что приложение перестает отвечать на запросы или использование памяти постоянно увеличивается с течением времени. Чтобы избежать этой проблемы, все потоки однопотоковых квартир (STA) должны использовать примитивы перекачки ожидания (такие как CoWaitForMultipleHandles) и регулярно перекачивать сообщения во время длительных операций.

SeaDrive
источник

Ответы:

287

Это ContextSwitchDeadlockне обязательно означает, что у вашего кода есть проблема, просто есть потенциал. Если вы зайдете Debug > Exceptionsв меню и развернете Managed Debugging Assistants, вы обнаружите, ContextSwitchDeadlockчто включен. Если вы отключите это, VS больше не будет предупреждать вас, когда для обработки элементов требуется много времени. В некоторых случаях у вас действительно может быть длительная операция. Также полезно, если вы выполняете отладку и остановились на линии во время обработки - вы не хотите, чтобы она жаловалась, прежде чем у вас появилась возможность разобраться в проблеме.

Pedro
источник
4
Право на! Спасибо. Мне нужно было перейти к настройке и добавить исключения в меню отладки. Не самый интуитивный аспект пользовательского интерфейса. Инструменты \ Настройка, затем Изменить порядок команд (кнопка), затем выберите Отладка в раскрывающемся меню справа вверху, затем Добавить (кнопка). Уф!
SeaDrive
81
ctrl-alt-eприносит диалог исключения.
Флориан Дойон
1
Многие из более свежих версий Visual Studio (2012, 2010, 2008) и, возможно, некоторые более ранние версии позволяют выбирать основное использование Visual Studio при первом запуске после установки. Этот выбор определяет макет панели инструментов по умолчанию, включая то, какие элементы управления являются видимыми или скрытыми, и даже какие нажатия клавиш соответствуют каким командам. В VS 2010 мастер импорта и экспорта настроек позволяет сбросить настройки до одного из доступных значений по умолчанию.
Зарепет
4
@ B.ClayShannon - ContextSwitchDeadlock относится к отладчику. Релиз версия exe не будет отображать это сообщение.
Педро
9
В VS 2013 Навигация с Debug -> Windows -> Exceptions Settings. Тогда воспользуйся поиском
Маркус Вебер
16

Как сказал Педро, у вас есть проблема с отладчиком, мешающим прокачке сообщений, если вы перебираете код.

Но если вы выполняете длительную операцию в потоке пользовательского интерфейса, тогда вызовите Application.DoEvents (), который явно прокачивает очередь сообщений и затем возвращает управление вашему текущему методу.

Однако, если вы делаете это, я бы порекомендовал взглянуть на ваш дизайн, чтобы вы могли выполнять обработку вне потока пользовательского интерфейса, чтобы ваш пользовательский интерфейс оставался красивым и быстрым.

кладовая для продуктов
источник
14

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

Вы должны посмотреть, как порождать фоновый поток для длительной работы, и вывести какое-то диалоговое окно «Я занят» для пользователя, пока это происходит.

Роб Уокер
источник
13

В Visual Studio 2017 снимите флажок с опции ContextSwitchDeadlock:

Отладка> Windows> Настройки исключений

введите описание изображения здесь

В Windows настройки исключений: снимите флажок ContextSwitchDeadlock

введите описание изображения здесь

Хасан Рахман
источник
9

Если вы не хотите отключать это исключение, все, что вам нужно сделать, это дать приложению возможность отправлять некоторые сообщения не реже одного раза в 60 секунд. Это предотвратит это исключение. Попробуйте вызывать System.Threading.Thread.CurrentThread.Join (10) время от времени. Есть и другие звонки, которые позволяют делать сообщения.


источник
Не могли бы вы объяснить, почему это помогает?
катится
Это не будет работать, у меня есть цикл обновления пользовательского интерфейса и все еще получаю сообщение об ошибке.
htm11h
1
Нет необходимости использовать значение 10 миллисекунд, фактически, если вы намерены вызывать его повторно в длительной операции, это сильно снизит общую производительность (общее время выполнения). Просто передайте ноль к нему.
ElektroStudios
У меня была похожая проблема. Нашел ваше решение, чтобы работать. Спасибо!
Sk Shahnawaz-ul Haque
2

Вышеупомянутое решение хорошо в некоторых сценариях, но есть другой сценарий, в котором это происходит, когда вы проводите модульное тестирование, и вы пытаетесь «Отладить выбранные тесты» из Test Explorer, когда для вашего решения не задано Debug.

В этом случае вам нужно сменить решение с версии Release или на то, что в этом случае установлено на Debug. Если это проблема, то изменение «ContextSwitchDeadlock» действительно не поможет вам.

Я пропустил это сам, потому что сообщение об ошибке было настолько неприятным, что я не проверял очевидную вещь - настройку отладки!

Ewan
источник
1

В Visual Studio 2017 испанская версия.

"Depurar" -> "Ventanas" -> "Configuración de Excepciones"

и поиск "ContextSwitchDeadlock". Затем снимите флажок. Или ярлык

CTRL + D, Е

Лучший.

kahonmlg
источник
0

Вы можете решить эту проблему, сняв флажок contextswitchdeadlock от

Отладка-> Исключения ... -> Развернуть узел MDA -> снять флажок -> contextswitchdeadlock

КР Ахиль
источник
0

Я получил эту ошибку и переключил запросы на асинхронный (await (...). ToListAsync ()). Все хорошо сейчас.

dunwan
источник