Visual Studio: ContextSwitchDeadlock

J'ai reçu un message d'erreur que je ne peux pas résoudre. Il provient de Visual Studio ou du débogueur. Je ne suis pas sûr si la condition d'erreur finale est dans VS, le débogueur, mon programme ou la database.

Ceci est une application Windows. Pas une application web.

Le premier message de VS est une window contextuelle disant: "Aucun symbole n'est chargé pour une trame de stack d'appel, le code source ne peut pas être affiché." Lorsque cela est cliqué, je reçois: " ContextSwitchDeadlock a été détecté ", avec un long message reproduit ci-dessous.

L'erreur se produit dans une boucle qui parsing un DataTable. Pour chaque ligne, il utilise une valeur de key (HIC #) de la table en tant que paramètre pour un SqlCommand. La command est utilisée pour créer un SqlDataReader qui returnne une ligne. Les données sont comparées. Si une erreur est détectée, une ligne est ajoutée à un second DataTable.

L'erreur semble être liée à la durée de la procédure (c.-à-d. Après 60 secondes), et non au nombre d'erreurs détectées. Je ne pense pas que ce soit un problème de memory. Aucune variable n'est déclarée dans la boucle. Les seuls objects créés sont SqlDataReaders et ils sont dans Utilisation des structures. Ajouter System.GC.Collect () n'a eu aucun effet.

Le db est un site SqlServer sur le même ordinateur portable.

Il n'y a pas de gadgets ou de gadgets sur le formulaire.

Je ne suis au courant de rien dans ce process qui soit très différent de ce que j'ai fait des dizaines de fois auparavant. J'ai déjà vu l'erreur, mais jamais de manière cohérente.

Des idées, quelqu'un?

Erreur complète Texte: Le CLR n'a pas pu passer du context COM 0x1a0b88 au context COM 0x1a0cf8 pendant 60 secondes. Le thread qui possède le context / appartement de destination est probablement en train de faire une attente sans pompage ou de traiter une opération très longue sans pomper les messages Windows. Cette situation a généralement un impact négatif sur les performances et peut même conduire à une non-réactivité de l'application ou à une accumulation continue de l'utilisation de la memory au fil du time. Pour éviter ce problème, tous les threads STA (single threaded apartment) doivent utiliser des primitives d'attente de pompage (telles que CoWaitForMultipleHandles) et pomper régulièrement des messages lors d'opérations longues.

ContextSwitchDeadlock ne signifie pas nécessairement que votre code a un problème, mais qu'il existe un potentiel. Si vous allez dans Debug > Exceptions dans le menu et développez les Managed Debugging Assistants , vous findez ContextSwitchDeadlock activé. Si vous désactivez cette option, VS ne vous avertira plus lorsque les éléments prendront beaucoup de time à traiter. Dans certains cas, vous pouvez avoir une opération de longue durée. Il est également utile si vous déboguez et que vous vous arrêtez sur une ligne pendant le traitement – vous ne voulez pas qu'il se plaint avant que vous ayez eu l'occasion de vous attaquer à un problème.

Comme l'a dit Pedro, vous avez un problème avec le débogueur empêchant le pompage de message si vous passez par le code.

Mais si vous effectuez une opération de longue durée sur le thread de l'interface user, appelez Application.DoEvents (), qui pompe explicitement la queue des messages, puis renvoie le contrôle à votre méthode actuelle.

Cependant si vous faites ceci je reorderais à regarder votre design de sorte que vous puissiez effectuer le traitement outre du fil d'interface user de sorte que votre interface user rest belle et vive.

Il semble que vous le fassiez sur le thread principal de l'interface user de l'application. Le thread d'interface user est chargé de pomper les messages Windows à l'arrivée, et pourtant, parce que le vôtre est bloqué dans les appels de database, il est incapable de le faire. Cela peut provoquer des problèmes avec les messages système.

Vous devriez chercher à générer un thread d'arrière-plan pour l'opération de longue durée et mettre en place une sorte de boîte de dialog "Je suis occupé" pour l'user pendant qu'il se produit.

Si vous ne voulez pas désactiver cette exception, tout ce que vous devez faire est de laisser votre application pomper des messages au less une fois toutes les 60 secondes. Cela empêchera cette exception. Essayez d'appeler System.Threading.Thread.CurrentThread.Join (10) de time en time. Il y a d'autres appels que vous pouvez faire pour que les messages pompent.

La solution ci-dessus est bonne dans certains scénarios, mais il existe un autre scénario où cela se produit lorsque vous effectuez un test unitaire et que vous essayez de "déboguer les tests sélectionnés" de l'Explorateur de test lorsque votre solution n'est pas définie sur Déboguer.

Dans ce cas, vous devez changer votre solution de Release ou de ce qu'elle est définie à Debug dans ce cas. Si c'est le problème, changer "ContextSwitchDeadlock" ne vous aidera pas vraiment.

J'ai manqué cela moi-même parce que le message d'erreur était si méchant que je n'ai pas vérifié la chose évidente qui était le réglage de debugging!

Dans Visual Studio 2017 version espagnole.

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

et searchz "ContextSwitchDeadlock". Ensuite, décochez-le. Ou raccourci

Ctrl + D, E

Meilleur.

Vous pouvez résoudre ce problème en désactivant contextswitchdeadlock à partir de

Déboguer-> Exceptions … -> Développer noeud MDA -> décocher -> contextswitchdeadlock