Visual Studio: ContextSwitchDeadlock

167

Ich habe eine Fehlermeldung erhalten, die ich nicht beheben kann. Es stammt aus Visual Studio oder dem Debugger. Ich bin nicht sicher, ob die endgültige Fehlerbedingung in VS, dem Debugger, meinem Programm oder der Datenbank liegt.

Dies ist eine Windows-App. Keine Web-App.

Die erste Nachricht von VS ist ein Popup-Fenster mit der Aufschrift: "Für keinen Aufrufstapel-Frame werden Symbole geladen. Der Quellcode kann nicht angezeigt werden." Wenn das weggeklickt wird, erhalte ich: " ContextSwitchDeadlock wurde erkannt ", zusammen mit einer langen Nachricht, die unten wiedergegeben wird.

Der Fehler tritt in einer Schleife auf, die eine DataTable durchsucht. Für jede Zeile wird ein Schlüsselwert (HIC #) aus der Tabelle als Parameter für einen SqlCommand verwendet. Mit dem Befehl wird ein SqlDataReader erstellt, der eine Zeile zurückgibt. Daten werden verglichen. Wenn ein Fehler erkannt wird, wird eine Zeile zu einer zweiten Datentabelle hinzugefügt.

Der Fehler scheint damit zu tun zu haben, wie lange die Prozedur dauert (dh nach 60 Sekunden), und nicht damit, wie viele Fehler gefunden werden. Ich denke nicht, dass es ein Speicherproblem ist. Innerhalb der Schleife werden keine Variablen deklariert. Die einzigen Objekte, die erstellt werden, sind die SqlDataReaders und befinden sich unter Verwenden von Strukturen. Das Hinzufügen von System.GC.Collect () hatte keine Auswirkung.

Die Datenbank ist eine SqlServer-Site auf demselben Laptop.

Das Formular enthält keine ausgefallenen Spielereien oder Gadgets.

Mir ist nichts in diesem Prozess bekannt, was sich stark von dem unterscheidet, was ich Dutzende Male zuvor getan habe. Ich habe den Fehler schon einmal gesehen, aber nie auf einer konsistenten Basis.

Irgendwelche Ideen, irgendjemand?

Vollständiger Fehlertext: Die CLR konnte 60 Sekunden lang nicht vom COM-Kontext 0x1a0b88 zum COM-Kontext 0x1a0cf8 wechseln. Der Thread, dem der Zielkontext / die Zielwohnung gehört, führt höchstwahrscheinlich entweder eine Wartezeit ohne Pumpen durch oder verarbeitet einen sehr lang laufenden Vorgang, ohne Windows-Nachrichten zu pumpen. Diese Situation wirkt sich im Allgemeinen negativ auf die Leistung aus und kann sogar dazu führen, dass die Anwendung nicht mehr reagiert oder sich die Speichernutzung im Laufe der Zeit kontinuierlich ansammelt. Um dieses Problem zu vermeiden, sollten alle Single-Threaded-Apartment-Threads (STA-Threads) Pump-Wait-Grundelemente (wie CoWaitForMultipleHandles) verwenden und Nachrichten bei langen Betriebsabläufen routinemäßig pumpen.

SeaDrive
quelle

Antworten:

287

Das ContextSwitchDeadlockbedeutet nicht unbedingt, dass Ihr Code ein Problem hat, nur dass es ein Potenzial gibt. Wenn Sie Debug > Exceptionsim Menü auf gehen und das erweitern Managed Debugging Assistants, werden Sie feststellen, dass ContextSwitchDeadlockaktiviert ist. Wenn Sie dies deaktivieren, werden Sie von VS nicht mehr gewarnt, wenn die Verarbeitung von Elementen lange dauert. In einigen Fällen haben Sie möglicherweise einen Betrieb mit langer Laufzeit. Es ist auch hilfreich, wenn Sie während der Verarbeitung debuggen und in einer Zeile angehalten haben. Sie möchten nicht, dass es sich beschwert, bevor Sie die Gelegenheit hatten, sich mit einem Problem zu befassen.

Pedro
quelle
4
Direkt am! Vielen Dank. Ich musste zum Anpassen gehen und Ausnahmen zum Debug-Menü hinzufügen. Nicht der intuitivste Aspekt der Benutzeroberfläche. Extras \ Anpassen, dann Befehle neu anordnen (Schaltfläche), dann Debuggen aus der Dropdown-Liste oben rechts auswählen und dann Hinzufügen (Schaltfläche). Wütend!
SeaDrive
81
ctrl-alt-ebringt den Ausnahmedialog.
Florian Doyon
1
In vielen neueren Versionen von Visual Studio (2012, 2010, 2008) und möglicherweise auch in früheren Versionen kann die primäre Verwendung von Visual Studio ausgewählt werden, wenn es nach der Installation zum ersten Mal ausgeführt wird. Diese Auswahl bestimmt das Standardlayout der Symbolleisten, einschließlich der sichtbaren oder ausgeblendeten Steuerelemente und sogar der Tastenanschläge, die welchen Befehlen entsprechen. In VS 2010 können Sie mit dem Assistenten für Import- und Exporteinstellungen auf einen der verfügbaren Standardeinstellungen zurücksetzen.
Zarepheth
4
@ B.ClayShannon - ContextSwitchDeadlock ist spezifisch für den Debugger. In einer Release-Version der Exe wird diese Meldung nicht angezeigt.
Pedro
9
In VS 2013 Navigieren mit Debug -> Windows -> Exceptions Settings. Dann benutzen Sie die Suche
Markus Weber
16

Wie Pedro sagte, haben Sie ein Problem mit dem Debugger, der die Nachrichtenpumpe verhindert, wenn Sie den Code durchlaufen.

Wenn Sie jedoch eine lange laufende Operation für den UI-Thread ausführen, rufen Sie Application.DoEvents () auf, das die Nachrichtenwarteschlange explizit pumpt und dann die Steuerung an Ihre aktuelle Methode zurückgibt.

Wenn Sie dies jedoch tun, würde ich empfehlen, sich Ihr Design anzusehen, damit Sie die Verarbeitung außerhalb des UI-Threads durchführen können, damit Ihre UI schön und bissig bleibt.

Spence
quelle
14

Es hört sich so an, als würden Sie dies im Haupt-UI-Thread der App tun. Der UI-Thread ist für das Pumpen von Windows-Nachrichten beim Eintreffen verantwortlich. Da Ihr Thread jedoch bei Datenbankaufrufen blockiert ist, kann er dies nicht tun. Dies kann Probleme mit systemweiten Nachrichten verursachen.

Sie sollten sich ansehen, wie Sie einen Hintergrund-Thread für den lang laufenden Vorgang erstellen und währenddessen eine Art "Ich bin beschäftigt" -Dialog für den Benutzer einrichten.

Rob Walker
quelle
13

Deaktivieren Sie in Visual Studio 2017 die Option ContextSwitchDeadlock durch:

Debug> Windows> Ausnahmeeinstellungen

Geben Sie hier die Bildbeschreibung ein

In Ausnahmeeinstellungsfenstern: Deaktivieren Sie die Option ContextSwitchDeadlock

Geben Sie hier die Bildbeschreibung ein

Hassan Rahman
quelle
9

Wenn Sie diese Ausnahme nicht deaktivieren möchten, müssen Sie Ihre Anwendung nur mindestens alle 60 Sekunden einige Nachrichten pumpen lassen. Dadurch wird diese Ausnahme verhindert. Versuchen Sie ab und zu, System.Threading.Thread.CurrentThread.Join (10) aufzurufen. Es gibt andere Anrufe, mit denen Sie die Nachrichten pumpen lassen können.


quelle
Können Sie erklären, warum dies hilft?
rollt
Dies wird nicht funktionieren, ich habe eine Schleife, die die Benutzeroberfläche aktualisiert und immer noch die Fehlermeldung erhält.
htm11h
1
Es ist nicht erforderlich, einen Wert von 10 Millisekunden zu verwenden. Wenn Sie ihn in einem lang laufenden Vorgang wiederholt aufrufen möchten, wird die Gesamtleistung (Gesamtzeitausführung) erheblich verringert. Übergeben Sie einfach Null.
ElektroStudios
Ich hatte ein ähnliches Problem. Ich habe festgestellt, dass Ihre Lösung funktioniert. Vielen Dank!
Sk Shahnawaz-ul Haque
2

Die obige Lösung ist in einigen Szenarien gut, aber es gibt ein anderes Szenario, in dem dies passiert, wenn Sie Unit-Tests durchführen und versuchen, ausgewählte Tests im Test-Explorer zu "debuggen", wenn Ihre Lösung nicht auf Debug eingestellt ist.

In diesem Fall müssen Sie Ihre Lösung von Release oder in diesem Fall auf Debug ändern. Wenn dies das Problem ist, hilft Ihnen das Ändern von "ContextSwitchDeadlock" nicht wirklich.

Ich habe das selbst verpasst, weil die Fehlermeldung so böse war, dass ich die offensichtliche Debug-Einstellung nicht überprüft habe!

Ewan
quelle
1

In der spanischen Version von Visual Studio 2017.

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

und suchen Sie nach "ContextSwitchDeadlock". Deaktivieren Sie es dann. Oder Verknüpfung

Strg + D, E.

Beste.

kahonmlg
quelle
0

Sie können dies lösen, indem Sie das Kontrollkästchen contextwitchdeadlock von deaktivieren

Debug-> Ausnahmen ... -> MDA-Knoten erweitern -> Deaktivieren -> Contextswitchdeadlock

KR Akhil
quelle
0

Ich habe diesen Fehler erhalten und die Abfragen auf async umgestellt (warte (...). ToListAsync ()). Alles gut jetzt.

Dunwan
quelle