82 votes

Erreur ContextSwitchDeadlock Was Detected en C#

J'exécute une application C#, et pendant l'exécution, je reçois l'erreur suivante :

Le CLR n'a pas pu effectuer la transition du contexte COM 0x20e480 au contexte COM 0x20e5f0 pendant 60 secondes. Le thread qui possède le contexte/appartement de destination est très probablement en train de faire une attente sans pompage ou de traiter une opération très longue sans pompage de messages Windows. Cette situation a généralement un impact négatif sur les performances et peut même conduire à ce que l'application devienne non réactive ou que l'utilisation de la mémoire s'accumule continuellement au fil du temps. Pour éviter ce problème, tous les threads d'appartement à fil unique (STA) devraient utiliser des primitives d'attente de pompage (telles que CoWaitForMultipleHandles) et pomper régulièrement des messages pendant les opérations de longue durée.

Quelqu'un peut-il m'aider à résoudre ce problème ?

Merci beaucoup.

125voto

Hans Passant Points 475940

Le thread principal de votre programme est occupé à exécuter du code depuis une minute. Il ne s'occupe pas de ses tâches normales, en pompant la boucle de messages. C'est illégal lorsque vous utilisez des serveurs COM dans un thread worker : les appels à leurs méthodes ne peuvent pas être distribués avant que votre thread principal ne soit à nouveau inactif.

Il doit être facilement visible, votre interface utilisateur doit être morte comme un clou de porte. Windows devrait avoir remplacé votre fenêtre principale par un fantôme qui affiche "Not Responding". La fermeture de la fenêtre ne fonctionne pas, aucun événement de clic n'a d'effet.

Ce que votre thread principal est en train de faire doit être fait par un worker thread à la place. Le site BackgroundWorker est idéale pour cela, vous trouverez de nombreuses aides à l'utilisation dans l'article de la bibliothèque MSDN la concernant. Utilisez Debug + Break All, Debug + Windows + Threads si vous n'avez aucune idée de ce que fait le thread principal.

Une autre cause possible : veillez à installer le Service Pack 1 si vous utilisez la version RTM de VS2005.

5 votes

+1 pour avoir expliqué qu'un tel point de travail devrait être déplacé vers un fil secondaire, donc la solution sur comment éviter cette erreur (plutôt que juste ce qui produit l'erreur).

2 votes

Il est intéressant de noter que j'ai vu quelques autres applications créées en interne se bloquer pendant beaucoup plus longtemps que la mienne, et pourtant j'ai reçu ce message d'erreur, hmmm.

0 votes

Documentation MSDN : MDA contextSwitchDeadlock msdn.microsoft.com/fr/us/library/ms172233%28v=vs.110%29.aspx

50voto

Scott Munro Points 4008

Pour trouver l'opération qui bloque le changement de contexte et qui provoque le message contextSwitchDeadlock MDA à afficher, vous pouvez suivre les étapes suivantes. Notez que je vais faire référence à Visual Studio 2012.

  1. Reproduisez l'erreur. Cela peut impliquer quelques essais et erreurs.
  2. Cliquez sur "OK" plutôt que sur "Continuer" dans l'assistant de débogage géré qui s'affiche.
  3. Vérifiez que la barre d'outils Debug Location est active en cliquant avec le bouton droit de la souris sur la zone d'ancrage de la barre d'outils et en sélectionnant "Debug Location". Si la barre d'outils est active, vous devriez voir apparaître une liste déroulante intitulée "Thread".
  4. L'élément sélectionné dans la liste déroulante Thread doit être un fil autre que le fil principal, car il s'agit d'un fil d'arrière-plan qui se plaint que le fil principal accapare toute l'attention. Sélectionnez le fil principal dans la liste déroulante.
  5. Vous devriez maintenant voir le code qui bloque le changement de contexte dans l'éditeur de code.

En supposant que vous décidiez de ne pas déplacer l'opération gourmande en ressources hors du fil d'exécution principal - jetez d'abord un coup d'œil à certaines des autres réponses et commentaires ici - vous disposez des options suivantes pour désactiver les assistants de débogage gérés.

Dans le débogueur de Visual Studio

  1. Vous pouvez désactiver un MDA directement dans la boîte de dialogue MDA qui s'affiche lorsque l'erreur se produit. qui s'affiche lorsque l'erreur se produit, en décochant la case "Break when this type d'exception est déclenché".
  2. Avec la boîte de dialogue Paramètres d'exception en suivant les instructions ci-dessous de MSDN .

...dans le menu Debug, cliquez sur Exceptions. (Si le menu Debug ne contient pas de commande Exceptions, cliquez sur Personnaliser dans le menu Outils pour l'ajouter). Dans la boîte de dialogue Exceptions, développez la liste Managed Debugging Assistants (assistants de débogage gérés), puis décochez la case Thrown (lancé) pour chaque MDA.

En dehors du débogueur de Visual Studio

  1. Clé de registre (A l'échelle de la machine, tous les MDAs concernés)
  2. Variable d'environnement (à l'échelle de la machine, les MDA peuvent être spécifiés)
  3. Paramètres de configuration de l'application (Champ d'application, les MDAs peuvent être spécifiés)

Note : L'une des deux premières options doit être mise à 1 pour que la troisième ait un effet.

Dans mon cas, le problème était un appel à ObjectContext.SaveChanges() dans l'Entity Framework au sein d'une application console. Avec le MTAThreadAttribute appliqué à la Main() méthode l'exception ContextSwitchDeadlock n'était plus levée . Je ne suis malheureusement pas certain des effets complets de ce changement.

2 votes

Upvote pour l'explication claire sur la recherche du code qui bloque le processus.

10voto

Franci Penov Points 45358

Ce message indique qu'une partie de votre code tente de changer de thread et que le thread cible est occupé. Par exemple, un thread d'arrière-plan essaie d'envoyer un appel au thread de l'interface utilisateur pour mettre à jour l'interface utilisateur, alors que l'interface utilisateur exécute une boucle serrée pendant un certain temps.

Pour comprendre ce qui se passe, il faut entrer dans le débogueur et examiner tous les threads et ce qu'ils font.

4voto

Ehsan Ershadi Points 1349

Dans certains cas :
Débogage -> Exceptions -> Assistants de débogage gérés
et décochez l'élément ContextSwitchDeadlock.

0 votes

Peut-être si vous étiez incroyablement désespéré, mais en tant que priorité élevée, je devrais revenir en arrière et réparer.

5 votes

Oui, mais lorsque vous écrivez un test unique et que cela vous gêne, il est agréable de pouvoir le désactiver.

4 votes

Non. Faux. Ce n'est pas une solution au problème.

0voto

Kumari Sony Points 27

Il suffit de sélectionner Exceptions dans le menu Debug de la fenêtre de Visual Studio 2005, la boîte de dialogue Edxception apparaîtra, sélectionnez le nœud Managed Debugging Assistants Exception, puis sélectionnez ContextSwitchDeadlock et supprimez la colonne select from Thrown. Cela empêchera le vs de lancer l'exception ContextSwitchDeadlock.

J'espère que cela vous aidera

60 votes

Ton bras est en feu. Il suffit d'utiliser un couteau pour couper le nerf qui envoie la douleur à votre cerveau. Cela vous empêchera de vous rendre compte que votre bras est en feu.

0 votes

En tout cas, c'est une façon de résoudre le problème temporairement. Pour éliminer complètement ce problème, il faut un certain temps pour reconsidérer la conception de l'application.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X