Je reçois 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 que la condition d'erreur ultime se trouve dans VS, le débogueur, mon programme ou la base de données.
Ceci est une application Windows. Pas une application web.
Le premier message de VS est une boîte de dialogue indiquant: "Aucun symbole n'est chargé pour une trame de pile d'appels. Le code source ne peut pas être affiché." Lorsque vous cliquez dessus, je reçois: " ContextSwitchDeadlock a été détecté ", avec un long message reproduit ci-dessous.
L'erreur se produit dans une boucle qui analyse un DataTable. Pour chaque ligne, il utilise une valeur de clé (HIC #) de la table en tant que paramètre pour SqlCommand. La commande est utilisée pour créer un SqlDataReader qui renvoie une ligne. Les données sont comparées. Si une erreur est détectée, une ligne est ajoutée à un deuxième DataTable.
L’erreur semble être liée au temps nécessaire à l’exécution de la procédure (c’est-à-dire au bout de 60 secondes) et non au nombre d’erreurs trouvées. Je ne pense pas que ce soit un problème de mémoire. Aucune variable n'est déclarée dans la boucle. Les seuls objets créés sont les SqlDataReaders. Ils se trouvent dans Utilisation des structures. Ajouter System.GC.Collect () n'a eu aucun effet.
La base de données est un site SqlServer sur le même ordinateur portable.
Il n'y a pas de gadgets ni de gadgets sophistiqués sur le formulaire.
Je ne suis au courant de rien dans ce processus qui soit très différent de ce que j'ai fait des dizaines de fois auparavant. J'ai déjà vu l'erreur auparavant, mais jamais de manière constante.
Des idées, n'importe qui?
Texte d'erreur complet: Le CLR n'a pas pu passer du contexte COM 0x1a0b88 au contexte COM 0x1a0cf8 pendant 60 secondes. Le thread qui possède le contexte/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 entraîner une non-réponse de l'application ou une utilisation de la mémoire de plus en plus longue. 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 les messages lors d'opérations de longue durée.
La ContextSwitchDeadlock
ne signifie pas nécessairement que votre code a un problème, mais simplement un potentiel. Si vous accédez à Debug > Exceptions
dans le menu et développez le Managed Debugging Assistants
, vous constaterez que ContextSwitchDeadlock
est activé. Si vous désactivez cette option, VS ne vous avertira plus lorsque le traitement des éléments prend beaucoup de temps. Dans certains cas, vous pouvez valablement exécuter une opération de longue durée. Il est également utile si vous êtes en train de déboguer et que vous vous êtes arrêté sur une ligne en cours de traitement. Vous ne voulez pas que celle-ci se plaint avant que vous ayez eu l'occasion de creuser un problème.
Comme Pedro l'a dit, vous avez un problème avec le débogueur qui empêche la pompe de message si vous parcourez le code.
Toutefois, si vous exécutez une opération de longue durée sur le thread d'interface utilisateur, appelez Application.DoEvents (), qui pompe explicitement la file d'attente de messages, puis redonne le contrôle à votre méthode actuelle.
Cependant, si vous faites cela, je vous conseillerais de regarder votre conception afin que vous puissiez effectuer un traitement à partir du fil de l'interface utilisateur afin que votre interface reste agréable et accrocheuse.
On dirait que vous faites cela sur le fil principal de l'interface utilisateur de l'application. Le thread d'interface utilisateur est chargé de pomper les messages Windows au fur et à mesure de l'arrivée, et pourtant, le vôtre étant bloqué dans les appels de base de données, il ne peut pas le faire. Cela peut causer des problèmes avec les messages système.
Vous devriez créer un thread d'arrière-plan pour l'opération longue et créer une sorte de boîte de dialogue "Je suis occupé" pour l'utilisateur pendant que cela se produit.
Si vous ne souhaitez pas désactiver cette exception, il vous suffit de laisser votre application envoyer des messages au moins une fois toutes les 60 secondes. Cela empêchera cette exception de se produire . Essayez d'appeler de temps en temps System.Threading.Thread.CurrentThread.Join (10). Vous pouvez faire d’autres appels pour que les messages soient diffusés.
La solution ci-dessus est bonne dans certains scénarios, mais il existe un autre scénario dans lequel cela se produit lorsque vous effectuez des tests unitaires et que vous essayez de "déboguer des tests sélectionnés" à partir de Test Explorer lorsque votre solution n'est pas définie sur Debug.
Dans ce cas, vous devez modifier votre solution à partir de Release ou ce qu'elle est définie sur Debug dans ce cas. Si tel est le problème, la modification de "ContextSwitchDeadlock" ne vous aidera pas vraiment.
J'ai raté 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 paramètre Debug!
Vous pouvez résoudre ce problème en décochant contexttswitchdeadlock de
Debug-> Exceptions ... -> Développez le nœud MDA -> décochez -> contextswitchdeadlock
Dans Visual Studio 2017 version espagnole.
"Depurar" -> "Ventanas" -> "Configuración de Excepciones"
et recherchez "ContextSwitchDeadlock". Ensuite, décochez-le. Ou raccourci
Ctrl + D, E
Meilleur.