Procédure pas à pas : Déboguer une application multithread à l’aide de la fenêtre Threads (C#, Visual Basic, C++)

Plusieurs éléments d’interface utilisateur Visual Studio vous aident à déboguer des applications multithread. Cet article présente les fonctionnalités de débogage multithread dans la fenêtre de l’éditeur de code, la barre d’outils Emplacement de débogage et la fenêtre Threads. Pour obtenir des informations sur d’autres outils de débogage d’applications multithread, consultez Bien démarrer avec le débogage d’applications multithread.

La réalisation de ce didacticiel ne prend que quelques minutes et vous familiarise avec les principes de base du débogage des applications multithread.

Créer un projet d’application multithread

Créez le projet d’application multithread suivant à utiliser dans ce didacticiel :

  1. Ouvrez Visual Studio et créez un projet.

    Si la fenêtre de démarrage n’est pas ouverte, choisissez Fichier>Fenêtre Démarrer.

    Dans la fenêtre de démarrage, choisissez Nouveau projet.

    Dans la fenêtre de démarrage, choisissez Créer un projet.

    Dans la fenêtre Créer un projet, entrez ou tapez console dans la zone de recherche. Ensuite, choisissez C# ou C++ dans la liste des langages, puis choisissez Windows dans la liste des plateformes.

    Après avoir appliqué les filtres de langage et de plateforme, choisissez Application console pour .NET Core, .NET 5+ ou C++ puis choisissez Suivant.

    Notes

    Si vous ne voyez pas le bon modèle, accédez à Outils>Obtenir des outils et fonctionnalités… pour ouvrir Visual Studio Installer. Choisissez la charge de travail Développement .NET Desktop ou Développement Desktop avec C++, puis choisissez Modifier.

    Dans la fenêtre Configurer votre nouveau projet, tapez un nom ou utilisez le nom par défaut dans la zone Nom du projet. Choisissez ensuite Suivant ou Créer, selon l’option disponible.

    Pour .NET Core ou .NET 5+, choisissez la version cible de .Net Framework recommandée ou .NET 8, puis choisissez Créer.

    Un nouveau projet console s'affiche. Une fois le projet créé, un fichier source s’affiche. En fonction du langage choisi, le fichier source peut être nommé Program.cs ou MyThreadWalkthroughApp.cpp.

  2. Remplacez le code dans le fichier source par l’exemple de code C# ou C++ issu de Bien démarrer avec le débogage d’applications multithread.

  3. Sélectionnez Fichier>Enregistrer tout.

Démarrer le débogage

  1. Recherchez les lignes suivantes dans le code source :

    Thread.Sleep(3000);
    Console.WriteLine();
    
  2. Définissez un point d’arrêt sur la ligne Console.WriteLine(); en cliquant dans la marge gauche ou en sélectionnant la ligne et en appuyant sur F9.

    Le point d’arrêt apparaît sous la forme d’un cercle rouge dans la marge gauche à côté de la ligne de code.

  3. Sélectionnez Déboguer>Démarrer le débogage ou appuyez sur F5.

    L’application démarre en mode débogage et s’interrompt au point d’arrêt.

  4. En mode arrêt, ouvrez la fenêtre Threads en sélectionnant Déboguer>Fenêtres>Threads. Vous devez être dans une session de débogage pour ouvrir ou voir les threads et autres fenêtres de débogage.

Examiner les marqueurs de thread

  1. Dans le code source, recherchez la ligne Console.WriteLine();.

    1. Cliquez avec le bouton droit dans la fenêtre Threads et sélectionnez Afficher les threads dans la sourceShow Threads in Source dans le menu.

    La marge située à côté de la ligne de code source affiche désormais une icône de marqueur de threadThread Marker. Le marqueur de thread indique qu'un thread est interrompu à cet emplacement. S’il y a plusieurs threads arrêtés à cet emplacement, l’icône de multiple threads s’affiche.

  2. Placez le pointeur sur le marqueur de thread. Un DataTip s’affiche, indiquant le nom et le numéro d’ID du ou des threads arrêtés. Les noms de threads peuvent être <No Name>.

    Conseil

    Pour identifier les threads sans nom, vous pouvez les renommer dans la fenêtre Threads. Effectuez un clic droit et sélectionnez Renommer.

  3. Cliquez avec le bouton droit sur le marqueur de thread dans le code source pour afficher les options disponibles dans le menu contextuel.

Ajouter et supprimer des threads

Vous pouvez marquer des threads pour suivre les threads auxquels vous souhaitez accorder une attention particulière.

Marquez les threads et supprimez leur marquage à partir de l’éditeur de code source ou de la fenêtre Threads. Choisissez d’afficher uniquement les threads marqués d’un indicateur, ou tous les threads, à partir des barres d’outils de la fenêtre Emplacement de débogage ou Threads. Les sélections effectuées à partir d’un emplacement quelconque affectent tous les emplacements.

Marquer les threads et supprimer leur marquage dans le code source

  1. Ouvrez la barre d’outils Emplacement de débogage en sélectionnant Affichage>Barres d’outils>Emplacement de débogage. Vous pouvez également cliquer avec le bouton droit dans la zone de barre d’outils et sélectionner Emplacement de débogage.

  2. La barre d’outils Emplacement de débogage comporte trois champs : Processus, Thread et Frame de pile. Déroulez la liste Thread et notez le nombre de threads qu’elle contient. Dans la liste Thread, le thread en cours d’exécution est marqué par un symbole >.

  3. Dans la fenêtre de code source, pointez sur une icône de marqueur de thread dans la marge et sélectionnez l’icône d’indicateur (ou l’une des icônes d’indicateur vides) dans le DataTip. L’icône d’indicateur devient rouge.

    Vous pouvez également cliquer avec le bouton droit sur une icône de marqueur de thread, pointer sur Indicateur, puis sélectionner un thread à marquer à partir du menu contextuel.

  4. Dans la barre d’outils Emplacement de débogage, sélectionnez l’icône Afficher uniquement les threads avec indicateurShow Flagged Threads, à droite du champ Thread. L’icône est grisée, sauf si un ou plusieurs threads sont marqués.

    Seul le thread avec indicateur apparaît désormais dans la liste déroulante Thread de la barre d’outils. Pour afficher à nouveau tous les threads, sélectionnez à nouveau l’icône Afficher uniquement les threads avec indicateur.

    Conseil

    Une fois que vous avez marqué certains threads, vous pouvez placer votre curseur dans l’éditeur de code, effectuer un clic droit et sélectionner Exécuter les threads avec indicateur au curseur. Veillez à choisir du code que tous les threads marqués d’un indicateur atteindront. L’option Exécuter les threads avec indicateur au curseur interrompt les threads sur la ligne de code sélectionnée, ce qui facilite le contrôle de l’ordre d’exécution en gelant et dégelant les threads.

  5. Pour activer l’état marqué ou non du thread en cours d’exécution, sélectionnez le bouton de barre d’outils Basculer l’état avec indicateur du thread actuel d’indicateur unique, à gauche du bouton Afficher seulement des threads avec indicateur. L’ajout d’un indicateur au thread actuel est utile pour localiser le thread actuel quand seuls les threads avec indicateur s’affichent.

  6. Pour supprimer l’indicateur d’un thread, pointez sur le marqueur du thread dans le code source et sélectionnez l’icône d’indicateur rouge pour l’effacer, ou cliquez avec le bouton droit sur le marqueur du thread et sélectionnez Supprimer l’indicateur.

Marquer les threads et supprimer leur indicateur dans la fenêtre Threads

Dans la fenêtre Threads, les threads marqués sont accompagnés d’icônes d’indicateur rouges, tandis que les threads sans indicateur, s’ils sont affichés, ont des icônes à contour vide.

Threads Window

Sélectionnez une icône d’indicateur pour modifier l’état du thread et le spécifier comme marqué ou sans indicateur, en fonction de son état actuel.

Vous pouvez également cliquer avec le bouton droit sur une ligne et sélectionner Indicateur, Supprimer l’indicateur ou Tous les threads sans indicateur dans le menu contextuel.

La barre d’outils de la fenêtre Threads a également un bouton Afficher uniquement les threads avec indicateur, qui correspond à l’icône de droite des deux icônes d’indicateur. Elle fonctionne de la même façon que le bouton de la barre d’outils Emplacement de débogage, et les deux boutons contrôlent l’affichage dans les deux emplacements.

Autres fonctionnalités de la fenêtre Threads

Dans la fenêtre Threads, sélectionnez l’en-tête d’une colonne pour trier les threads en fonction de cette colonne. Sélectionnez à nouveau pour inverser l’ordre de tri. Si tous les threads s’affichent, la sélection de la colonne d’icône d’indicateur trie les threads par état marqué ou sans indicateur.

La deuxième colonne de la fenêtre Threads (sans en-tête) est la colonne Thread actuel . Une flèche jaune dans cette colonne marque le point d’exécution actuel.

La colonne Emplacement indique l’emplacement où chaque thread apparaît dans le code source. Sélectionnez la flèche de développement située à côté de l’entrée Emplacement ou pointez sur l’entrée pour afficher une pile d’appels partielle pour ce thread.

Conseil

Pour obtenir une vue graphique des piles d’appels pour les threads, utilisez la fenêtre Piles parallèles. Pour ouvrir la fenêtre, lors du débogage, sélectionnez Déboguer>Fenêtres>Piles parallèles.

En plus de Ajouter un indicateur, Supprimer l’indicateur et Tous les threads sans indicateur, le menu contextuel du bouton droit pour les éléments de la fenêtre Thread comporte les éléments suivants :

  • Bouton Afficher les threads dans la source.
  • Affichage hexadécimal, qui convertit les ID de thread dans la fenêtre Threads du format décimal au format hexadécimal.
  • Basculer vers le thread, qui bascule immédiatement l’exécution vers ce thread.
  • Renommer, qui vous permet de modifier le nom du thread.
  • Commandes Figer et dégeler.

Figer et dégeler l’exécution des threads

Vous pouvez geler et dégeler, ou suspendre et reprendre, des threads pour contrôler l’ordre dans lequel les threads effectuent le travail. Le fait de geler et de dégeler des threads peut vous aider à résoudre les problèmes d’accès concurrentiel, tels que les blocages et les conditions de concurrence.

Conseil

Pour suivre un thread unique sans geler d’autres threads, ce qui est également un scénario de débogage courant, consultez Bien démarrer avec le débogage d’applications multithreads.

Pour figer et libérer des threads :

  1. Dans la fenêtre Threads, cliquez avec le bouton droit sur un thread, puis sélectionnez Figer. Une icône Pause dans la colonne Thread actuel indique que le thread est figé.

  2. Sélectionnez Colonnes dans la barre d’outils de la fenêtre Threads, puis sélectionnez Compteur suspendu pour afficher la colonne Compteur suspendu. La valeur du compteur suspendu pour le thread gelé est 1.

  3. Cliquez avec le bouton droit sur le thread figé et sélectionnez Libérer.

    L’icône Pause disparaît et la valeur Compteur suspendu passe à 0.

Basculer vers un autre thread

Une fenêtre L’application est en mode Arrêt peut s’afficher lorsque vous essayez de basculer vers un autre thread. Cette fenêtre vous indique que le thread n’a pas de code que le débogueur actuel peut afficher. Par exemple, vous déboguez peut-être du code managé, mais le thread est du code natif. La fenêtre propose des suggestions pour résoudre le problème.

Pour basculer vers un autre thread :

  1. Dans la fenêtre Threads, notez l’ID de thread actuel, qui est le thread avec une flèche jaune dans la colonne Thread actuel. Vous souhaiterez revenir à ce thread pour continuer votre application.

  2. Cliquez avec le bouton droit sur un autre thread et sélectionnez Basculer vers le thread dans le menu contextuel.

  3. Observez que l’emplacement de la flèche jaune a changé dans la fenêtre Threads. Le marqueur de thread actuel d’origine reste également, sous forme de plan.

    Examinez l’info-bulle sur le marqueur de thread dans l’éditeur de code source et la liste déroulante Thread dans la barre d’outils Emplacement de débogage. Notez que le thread actuel a également changé.

  4. Dans la barre d’outils Emplacement de débogage, sélectionnez un autre thread dans la liste Thread. Notez que le thread actuel change également dans les deux autres emplacements.

  5. Dans l’éditeur de code source, cliquez avec le bouton droit sur un marqueur de thread, pointez sur Basculer vers le thread, puis sélectionnez un autre thread dans la liste. Observez que le thread actuel change dans les trois emplacements.

Avec le marqueur de thread dans le code source, vous pouvez basculer uniquement vers les threads interrompus à cet emplacement. La fenêtre Threads et la barre d’outils Emplacement de débogage vous permettent de basculer vers n’importe quel thread.

Vous avez maintenant appris les principes de base du débogage d’applications multithread. Vous pouvez observer des threads, marquer des threads et supprimer leur indicateur, ainsi que geler et dégeler des threads à l’aide de la fenêtre Threads, de la liste Thread dans la barre d’outils Emplacement de débogage ou des marqueurs de thread dans l’éditeur de code source.