Візуальна студія: ContextSwitchDeadlock


167

Я отримував повідомлення про помилку, яке не можу вирішити. Він походить від Visual Studio або налагоджувача. Я не впевнений, чи є кінцева помилка у VS, відладчику, моїй програмі чи базі даних.

Це додаток для Windows. Не веб-додаток.

Перше повідомлення від VS - це спливаюче вікно, яке говорить: "Ніякі символи не завантажуються для жодного кадру стека викликів. Вихідний код не може бути відображений". Коли це натискається, я отримую: " ContextSwitchDeadlock було виявлено ", а також довге повідомлення, відтворене нижче.

Помилка виникає в циклі, який сканує таблицю даних. Для кожного рядка використовується ключове (HIC #) значення з таблиці як параметр для SqlCommand. Команда використовується для створення SqlDataReader, який повертає один рядок. Дані порівнюються Якщо виявлена ​​помилка, рядок додається до другої таблиці даних.

Здається, помилка пов’язана з тим, як триває процедура (тобто через 60 сек), а не скільки помилок. Я не думаю, що це питання пам’яті. В циклі не оголошено змінних. Єдині об'єкти, які створюються, - це SqlDataReaders, і вони знаходяться у використанні структур. Додати System.GC.Collect () не вплинуло.

Db є сайтом SqlServer на тому ж ноутбуці.

У Формі немає фантазійних штучок чи гаджетів.

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

Будь-які ідеї, хтось?

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

Відповіді:


287

Це ContextSwitchDeadlockне обов'язково означає, що ваш код має проблему, лише що є потенціал. Якщо ви перейдете до Debug > Exceptionsменю та розгорнете його Managed Debugging Assistants, ви знайдете, що ContextSwitchDeadlockце ввімкнено. Якщо ви відключите цю функцію, VS більше не попереджатиме вас, коли обробка елементів триває довгий час. У деяких випадках у вас може бути тривала операція. Це також корисно, якщо ви налагоджуєте помилку та зупиняєтесь на лінії під час опрацювання - ви не хочете, щоб вона скаржилася, перш ніж ви мали можливість скористатися проблемою.


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. Тоді використовуйте пошук
Markus Weber

16

Як сказав Педро, у вас є проблема з налагоджувачем, який запобігає накачуванню повідомлень, якщо ви переглядаєте код.

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

Однак якщо ви це робите, я рекомендую подивитися на ваш дизайн, щоб ви могли виконувати обробку з потоку інтерфейсу, щоб ваш інтерфейс залишався гарним і спритним.


14

Це здається, що ви робите це на головній темі інтерфейсу в додатку. Потік користувальницького інтерфейсу відповідає за перекачування повідомлень Windows під час надходження, але, оскільки ваше заблоковано у викликах бази даних, він не може цього зробити. Це може спричинити проблеми з повідомленнями, що мають широкий розмір системи.

Ви повинні подивитися на нерестування фонової нитки для тривалої операції та встановити якийсь діалог "я зайнятий" для користувача, поки це відбувається.


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

Вищевказане рішення є хорошим у деяких сценаріях, але є інший сценарій, коли це відбувається, коли ви перевіряєте одиницю, і ви намагаєтесь "Налагодити вибрані тести" з Тестового провідника, коли для вашого рішення не встановлено налагодження.

У цьому випадку вам потрібно змінити своє рішення на Release або все, що в цьому випадку встановлено на Debug. Якщо це проблема, то зміна "ContextSwitchDeadlock" насправді вам не допоможе.

Я сам пропустив це, оскільки повідомлення про помилку було настільки неприємним, що я не перевірив очевидну річ, яка була налаштуванням налагодження!


1

У Visual Studio 2017 іспанська версія.

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

і пошук "ContextSwitchDeadlock". Потім зніміть його. Або ярлик

Ctrl + D, E

Найкраще.


0

Ви можете вирішити це, знявши позначку з контексту

Налагодження-> Винятки ... -> Розгорнути вузол MDA -> зняти прапорець -> contextswitchdeadlock


0

Я отримав цю помилку і переключив запити на асинхронізацію (wait (...). ToListAsync ()). Все добре зараз.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.