Visual Studio: ContextSwitchDeadlock


167

Ho ricevuto un messaggio di errore che non riesco a risolvere. Proviene da Visual Studio o dal debugger. Non sono sicuro se la condizione di errore finale sia in VS, nel debugger, nel mio programma o nel database.

Questa è un'app di Windows. Non un'app Web.

Il primo messaggio da VS è una finestra pop-up che dice: "Nessun simbolo viene caricato per qualsiasi frame dello stack di chiamate. Il codice sorgente non può essere visualizzato." Quando viene cliccato, ottengo: " ContextSwitchDeadlock è stato rilevato ", insieme a un lungo messaggio riprodotto di seguito.

L'errore si verifica in un ciclo che esegue la scansione di una DataTable. Per ogni riga, utilizza un valore chiave (HIC #) dalla tabella come parametro per un comando Sql. Il comando viene utilizzato per creare un SqlDataReader che restituisce una riga. I dati vengono confrontati. Se viene rilevato un errore, viene aggiunta una riga a una seconda DataTable.

L'errore sembra essere correlato al tempo necessario per l'esecuzione della procedura (ovvero dopo 60 secondi), non al numero di errori rilevati. Non penso sia un problema di memoria. Nessuna variabile è dichiarata all'interno del ciclo. Gli unici oggetti che vengono creati sono gli SqlDataReaders e si trovano in Uso delle strutture. Aggiungi System.GC.Collect () non ha avuto effetto.

Il db è un sito SqlServer sullo stesso laptop.

Non ci sono aggeggi o gadget fantasiosi nel modulo.

Non sono a conoscenza di nulla in questo proc che è molto diverso da quello che ho fatto dozzine di volte prima. Ho visto l'errore prima, ma mai su una base coerente.

Qualche idea, qualcuno?

Testo di errore completo: CLR non è stato in grado di passare dal contesto COM 0x1a0b88 al contesto COM 0x1a0cf8 per 60 secondi. Il thread proprietario del contesto / appartamento di destinazione sta probabilmente eseguendo un'attesa non di pompaggio o elaborando un'operazione di esecuzione molto lunga senza pompare i messaggi di Windows. Questa situazione ha generalmente un impatto negativo sulle prestazioni e può persino portare all'applicazione che non risponde o all'utilizzo della memoria che si accumula continuamente nel tempo. Per evitare questo problema, tutti i thread STA (single threaded apartment) dovrebbero utilizzare primitive di attesa di pompaggio (come CoWaitForMultipleHandles) e pompare regolarmente i messaggi durante le operazioni di lunga durata.

Risposte:


287

Il ContextSwitchDeadlocknon significa necessariamente che il codice ha un problema, solo che c'è un potenziale. Se vai Debug > Exceptionsnel menu ed espandi Managed Debugging Assistants, troverai che ContextSwitchDeadlockè abilitato. Se lo disabiliti, VS non ti avvertirà più quando gli articoli impiegano molto tempo per l'elaborazione. In alcuni casi potresti avere validamente un'operazione di lunga durata. È anche utile se stai eseguendo il debug e ti sei fermato su una linea mentre questo è in elaborazione - non vuoi che si lamenta prima di avere la possibilità di scavare in un problema.


4
Bene! Grazie. Ho dovuto andare su Personalizza e aggiungere Eccezioni al menu Debug. Non è l'aspetto più intuitivo dell'interfaccia utente. Strumenti \ Personalizza, quindi Riordina comandi (pulsante), quindi Seleziona debug dal menu a discesa in alto a destra, quindi Aggiungi (pulsante). Meno male!
SeaDrive,

81
ctrl-alt-eporta la finestra di dialogo delle eccezioni.
Florian Doyon,

1
Molte delle versioni più recenti di Visual Studio (2012, 2010, 2008) e possibilmente alcune precedenti, consentono di scegliere l'uso principale di Visual Studio al primo avvio dopo l'installazione. Tale scelta determina il layout predefinito delle barre degli strumenti, incluso quali controlli sono visibili o nascosti e anche quali sequenze di tasti corrispondono a quali comandi. In VS 2010, la procedura guidata Importa ed esporta impostazioni consente di ripristinare uno dei valori predefiniti disponibili.
Zarepheth,

4
@ B.ClayShannon - ContextSwitchDeadlock è specifico per il debugger. Una versione di rilascio di exe non visualizzerà questo messaggio.
Pedro,

9
In VS 2013 Navigare con Debug -> Windows -> Exceptions Settings. Quindi utilizzare la ricerca
Markus Weber il

16

Come ha detto Pedro, hai un problema con il debugger che impedisce al pump dei messaggi se stai attraversando il codice.

Ma se stai eseguendo un'operazione di lunga durata sul thread dell'interfaccia utente, chiama Application.DoEvents () che pompa esplicitamente la coda dei messaggi e quindi restituisce il controllo al metodo corrente.

Tuttavia, se lo stai facendo, ti consiglio di guardare il tuo design in modo che tu possa eseguire l'elaborazione dal thread dell'interfaccia utente in modo che l'interfaccia utente rimanga bella e scattante.


14

Sembra che tu lo stia facendo sul thread dell'interfaccia utente principale nell'app. Il thread dell'interfaccia utente è responsabile del pompaggio dei messaggi di Windows all'arrivo, e tuttavia poiché il tuo è bloccato nelle chiamate al database non è in grado di farlo. Ciò può causare problemi con i messaggi di sistema.

Dovresti cercare di generare un thread in background per l'operazione di lunga durata e creare una sorta di finestra di dialogo "Sono occupato" per l'utente mentre succede.


13

In Visual Studio 2017, deselezionata l'opzione ContextSwitchDeadlock da:

Debug> Windows> Impostazioni eccezioni

inserisci qui la descrizione dell'immagine

In Eccezione per l'impostazione di Windows: deseleziona l'opzione ContextSwitchDeadlock

inserisci qui la descrizione dell'immagine


9

Se non si desidera disabilitare questa eccezione, è sufficiente lasciare che l'applicazione invii alcuni messaggi almeno una volta ogni 60 secondi. Impedirà che si verifichi questa eccezione. Prova a chiamare System.Threading.Thread.CurrentThread.Join (10) di tanto in tanto. Ci sono altre chiamate che puoi fare per far pompare i messaggi.


Potresti spiegare perché questo aiuta?
lancia il

Questo non funzionerà, ho un ciclo di aggiornamento dell'interfaccia utente e ricevo ancora il messaggio di errore.
htm11h

1
Non è necessario utilizzare un valore di 10 millisecondi, infatti se si intende chiamarlo ripetutamente in un'operazione di lunga durata, ciò ridurrà di molto le prestazioni complessive (esecuzione del tempo totale). Basta passare lo zero ad esso.
ElektroStudios,

Ho avuto un problema simile. Ho trovato la tua soluzione funzionante. Grazie!
Sk Shahnawaz-ul Haque,

2

La soluzione sopra è valida in alcuni scenari, ma esiste un altro scenario in cui ciò si verifica quando si eseguono test di unità e si tenta di "Debug dei test selezionati" da Test Explorer quando la soluzione non è impostata su Debug.

In questo caso, è necessario modificare la soluzione da Release o da qualsiasi cosa sia impostata su Debug in questo caso. Se questo è il problema, cambiare "ContextSwitchDeadlock" non ti sarà di grande aiuto.

L'ho perso anch'io perché il messaggio di errore era così brutto da non controllare la cosa ovvia che era l'impostazione di debug!


1

In Visual Studio 2017 versione spagnola.

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

e cerca "ContextSwitchDeadlock". Quindi deselezionalo. O scorciatoia

Ctrl + D, E

Migliore.


0

Puoi risolverlo deselezionando i contesti da cui è possibile disattivare il blocco

Debug-> Eccezioni ... -> Espandi nodo MDA -> deseleziona -> contextswitchdeadlock


0

Stavo ricevendo questo errore e ho cambiato le query in asincrono (await (...). ToListAsync ()). Va tutto bene adesso.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.