221 Stimmen

Visual Studio: ContextSwitchDeadlock

Ich habe eine Fehlermeldung erhalten, die ich nicht beheben kann. Sie stammt von Visual Studio oder dem Debugger. Ich bin mir nicht sicher, ob die eigentliche Fehlerbedingung in VS, im Debugger, in meinem Programm oder in der Datenbank liegt.

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

Die erste Meldung von VS ist ein Popup-Fenster mit der Meldung: "Es sind keine Symbole für einen Aufrufstapelrahmen geladen. Der Quellcode kann nicht angezeigt werden." Wenn das weggeklickt wird, erhalte ich: " ContextSwitchDeadlock wurde entdeckt ", zusammen mit einer langen Nachricht, die im Folgenden wiedergegeben wird.

Der Fehler tritt in einer Schleife auf, in der eine DataTable durchsucht wird. Für jede Zeile wird ein Schlüsselwert (HIC #) aus der Tabelle als Parameter für einen SqlCommand verwendet. Der Befehl wird verwendet, um einen SqlDataReader zu erstellen, der eine Zeile zurückgibt. Die Daten werden verglichen. Wird ein Fehler festgestellt, wird eine Zeile zu einer zweiten DataTable hinzugefügt.

Der Fehler scheint damit zusammenzuhängen, wie lange die Prozedur dauert (d. h. nach 60 Sekunden), und nicht damit, wie viele Fehler gefunden werden. Ich glaube nicht, dass es ein Speicherproblem ist. Innerhalb der Schleife werden keine Variablen deklariert. Die einzigen Objekte, die erstellt werden, sind die SqlDataReader, und sie befinden sich in Using-Strukturen. Das Hinzufügen von System.GC.Collect() hatte keine Wirkung.

Die Datenbank ist eine SqlServer-Site auf demselben Laptop.

Das Formular enthält keine ausgefallenen Spielereien oder Gadgets.

Mir ist nichts bekannt, was sich wesentlich von dem unterscheidet, was ich schon dutzende Male gemacht habe. Ich habe den Fehler schon einmal gesehen, aber nie auf einer konsistenten Basis.

Hat jemand eine Idee?

Vollständiger Fehlertext: Die CLR war 60 Sekunden lang nicht in der Lage, vom COM-Kontext 0x1a0b88 zum COM-Kontext 0x1a0cf8 zu wechseln. Der Thread, der den Zielkontext/das Ziel-Apartment besitzt, führt höchstwahrscheinlich entweder ein nicht pumpendes Warten durch oder verarbeitet eine sehr lange laufende Operation ohne das Pumpen von Windows-Nachrichten. Diese Situation wirkt sich im Allgemeinen negativ auf die Leistung aus und kann sogar dazu führen, dass die Anwendung nicht mehr reagiert oder die Speichernutzung im Laufe der Zeit kontinuierlich ansteigt. Um dieses Problem zu vermeiden, sollten alle Single Threaded Apartment (STA) Threads pumping wait primitives (wie CoWaitForMultipleHandles) verwenden und routinemäßig Nachrichten während lang laufender Operationen pumpen.

360voto

Pedro Punkte 11731

Le site ContextSwitchDeadlock bedeutet nicht zwangsläufig, dass Ihr Code ein Problem hat, sondern nur, dass es ein Potenzial gibt. Wenn Sie zu Debug > Exceptions im Menü und erweitern Sie den Managed Debugging Assistants finden Sie ContextSwitchDeadlock aktiviert ist.

Wenn Sie diese Funktion deaktivieren, werden Sie von VS nicht mehr gewarnt, wenn die Bearbeitung von Artikeln lange dauert. In einigen Fällen kann es durchaus vorkommen, dass ein Vorgang lange dauert. Es ist auch hilfreich, wenn Sie debuggen und in einer Zeile angehalten haben, während dies verarbeitet wird - Sie wollen nicht, dass es sich beschwert, bevor Sie eine Chance hatten, ein Problem zu untersuchen.

4 Stimmen

Genau richtig! Danke! Ich musste zu Anpassen gehen und Ausnahmen zum Menü Debuggen hinzufügen. Nicht der intuitivste Aspekt der Benutzeroberfläche. Werkzeuge \Customize , dann Befehle neu anordnen (Schaltfläche), dann Debug aus der Dropdown-Liste oben rechts auswählen, dann Hinzufügen (Schaltfläche). Uff!

0 Stimmen

Ja, bei einigen Installationen scheint dies im Menü zu stehen, bei anderen nicht. Ich habe das auch bei anderen nützlichen Menüpunkten gesehen, und ich muss noch herausfinden, was sie standardmäßig ein- oder ausschaltet.

107 Stimmen

ctrl-alt-e bringt den Ausnahmedialog.

57voto

Hassan Rahman Punkte 4337

Deaktivieren Sie in Visual Studio 2017 die Option ContextSwitchDeadlock durch:

Debuggen > Fenster > Ausnahmeeinstellungen

enter image description here

In Ausnahmeeinstellung Fenster: Deaktivieren Sie die Option ContextSwitchDeadlock

enter image description here

0 Stimmen

Funktioniert noch in VS 2019 Pro

22voto

Spence Punkte 27536

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

Wenn Sie jedoch eine lang andauernde Operation auf dem UI-Thread durchführen, rufen Sie Application.DoEvents() auf, die explizit die Nachrichtenwarteschlange pumpt und dann die Kontrolle an Ihre aktuelle Methode zurückgibt.

Wenn Sie dies jedoch tun, würde ich empfehlen, Ihr Design so zu gestalten, dass Sie die Verarbeitung außerhalb des UI-Threads durchführen können, damit Ihre Benutzeroberfläche schön und schnell bleibt.

17voto

Rob Walker Punkte 45267

Es klingt, als würden Sie dies im Haupt-UI-Thread der Anwendung tun. Der UI-Thread ist für das Pumpen von Windows-Nachrichten verantwortlich, wenn diese ankommen, und da Ihr Thread durch Datenbankaufrufe blockiert ist, kann er dies nicht tun. Dies kann zu Problemen mit systemweiten Nachrichten führen.

Sie sollten einen Hintergrund-Thread für die lang andauernde Operation erstellen und eine Art "Ich bin beschäftigt"-Dialog für den Benutzer einblenden, während dies geschieht.

10voto

Wenn Sie diese Ausnahme nicht deaktivieren wollen, müssen Sie nur dafür sorgen, dass Ihre Anwendung mindestens einmal alle 60 Sekunden einige Nachrichten ausgibt. Das wird diese Ausnahme verhindern. Versuchen Sie, hin und wieder System.Threading.Thread.CurrentThread.Join(10) aufzurufen. Es gibt noch andere Aufrufe, die die Nachrichten pumpen lassen.

0 Stimmen

Könnten Sie erklären, warum dies hilfreich ist?

0 Stimmen

Das wird nicht funktionieren, ich habe eine Schleife, die die Benutzeroberfläche aktualisiert, und erhalte immer noch die Fehlermeldung.

1 Stimmen

Es besteht keine Notwendigkeit, einen Wert von 10 Millisekunden zu verwenden. Wenn Sie beabsichtigen, die Funktion in einem lang laufenden Vorgang wiederholt aufzurufen, wird dies die Gesamtleistung (Gesamtzeit der Ausführung) erheblich verringern. Übergeben Sie ihm einfach den Wert Null.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X