Partager via


Diagnostiquer les délais de l’interface utilisateur causés par les extensions

Lorsque l’interface utilisateur ne répond plus, Visual Studio examine la pile des appels du thread d’interface utilisateur, en commençant par la feuille et en travaillant vers la base. Si Visual Studio détermine qu’une trame de pile d’appels appartient à un module qui fait partie d’une extension installée et activée, il affiche une notification.

UI delay (unresponsiveness) Notification

La notification informe l’utilisateur que le délai de l’interface utilisateur (autrement dit, l’absence de réponse dans l’interface utilisateur) a peut-être été le résultat du code d’une extension. Il fournit également à l’utilisateur des options permettant de désactiver l’extension ou les notifications futures pour cette extension.

Ce document décrit comment diagnostiquer ce qui se trouve dans votre code d’extension provoque des notifications de retard d’interface utilisateur.

Remarque

N’utilisez pas l’instance expérimentale Visual Studio pour diagnostiquer les retards de l’interface utilisateur. Certaines parties de l’analyse de pile des appels requises pour les notifications de retard d’interface utilisateur sont désactivées lors de l’utilisation de l’instance expérimentale, ce qui signifie que les notifications de retard de l’interface utilisateur peuvent ne pas être affichées.

Voici une vue d’ensemble du processus de diagnostic :

  1. Identifiez le scénario de déclencheur.
  2. Redémarrez VS avec la journalisation d’activité.
  3. Démarrez le suivi ETW.
  4. Déclenchez la notification pour qu’elle s’affiche à nouveau.
  5. Arrêtez le suivi ETW.
  6. Examinez le journal d’activité pour obtenir l’ID de délai.
  7. Analysez la trace ETW à l’aide de l’ID de délai de l’étape 6.

Dans les sections suivantes, nous allons suivre ces étapes plus en détail.

Identifier le scénario de déclencheur

Pour diagnostiquer un délai d’interface utilisateur, vous devez d’abord identifier ce qui (séquence d’actions) entraîne l’affichage de la notification par Visual Studio. Cela vous permet de déclencher la notification ultérieurement avec l’activation de la journalisation.

Redémarrer VS avec la journalisation d’activité sur

Visual Studio peut générer un « journal d’activité » qui fournit des informations utiles lors du débogage d’un problème. Pour activer la journalisation des activités dans Visual Studio, ouvrez Visual Studio avec l’option /log de ligne de commande. Une fois Visual Studio démarré, le journal d’activité est stocké à l’emplacement suivant :

%APPDATA%\Microsoft\VisualStudio\<vs_instance_id>\ActivityLog.xml

Pour en savoir plus sur la façon dont vous pouvez trouver votre ID d’instance VS, consultez Outils pour détecter et gérer des instances Visual Studio. Nous allons utiliser ce journal d’activité ultérieurement pour en savoir plus sur les retards de l’interface utilisateur et les notifications associées.

Démarrage du suivi ETW

Vous pouvez utiliser PerfView pour collecter une trace ETW. PerfView fournit une interface facile à utiliser pour collecter une trace ETW et l’analyser. Utilisez la commande suivante pour collecter une trace :

Perfview.exe collect C:\trace.etl /BufferSizeMB=1024 -CircularMB:2048 -Merge:true -Providers:*Microsoft-VisualStudio:@StacksEnabled=true -NoV2Rundown /kernelEvents=default+FileIOInit+ContextSwitch+Dispatcher

Cela permet au fournisseur « Microsoft-VisualStudio », qui est le fournisseur que Visual Studio utilise pour les événements liés aux notifications de retard de l’interface utilisateur. Il spécifie également l’mot clé pour le fournisseur de noyau que PerfView peut utiliser pour générer la vue Piles de temps de thread.

Déclencher la notification pour qu’elle s’affiche à nouveau

Une fois que PerfView a démarré la collection de traces, vous pouvez utiliser la séquence d’actions de déclencheur (à l’étape 1) pour que la notification apparaisse à nouveau. Une fois la notification affichée, vous pouvez arrêter la collecte de traces pour PerfView afin de traiter et de générer le fichier de trace de sortie.

Arrêter le suivi ETW

Pour arrêter la collection de traces, utilisez simplement le bouton Arrêter la collection dans la fenêtre PerfView. Après avoir arrêté la collecte de traces, PerfView traite automatiquement les événements ETW et génère un fichier de trace de sortie.

Examiner le journal d’activité pour obtenir l’ID de délai

Comme mentionné précédemment, vous trouverez le journal d’activité dans %APPDATA%\Microsoft\VisualStudio<vs_instance_id>\ActivityLog.xml. Chaque fois que Visual Studio détecte un délai d’interface utilisateur d’extension, il écrit un nœud dans le journal d’activité avec UIDelayNotifications comme source. Ce nœud contient quatre informations sur le délai d’interface utilisateur :

  • ID de délai d’interface utilisateur, nombre séquentiel qui identifie de façon unique un retard d’interface utilisateur dans une session VS
  • ID de session, qui identifie de manière unique votre session Visual Studio du début à la fermeture
  • Indique si une notification a été affichée ou non pour le délai de l’interface utilisateur
  • Extension qui a probablement provoqué le retard de l’interface utilisateur
<entry>
  <record>271</record>
  <time>2018/02/03 12:02:52.867</time>
  <type>Information</type>
  <source>UIDelayNotifications</source>
  <description>A UI delay (Delay ID = 0) has been detected. (Session ID=16e49d4b-26c2-4247-ad1c-488edeb185e0; Blamed extension="UIDelayR2"; Notification shown? Yes.)</description>
</entry>

Remarque

Tous les retards de l’interface utilisateur n’entraînent pas de notification. Par conséquent, vous devez toujours case activée la valeur de notification affichée ? pour identifier correctement le bon délai d’interface utilisateur.

Après avoir trouvé le délai d’interface utilisateur correct dans le journal d’activité, notez l’ID de délai d’interface utilisateur spécifié dans le nœud. Vous allez utiliser l’ID pour rechercher l’événement ETW correspondant à l’étape suivante.

Analyser la trace ETW

Ensuite, ouvrez le fichier de trace. Pour ce faire, vous pouvez utiliser la même instance de PerfView ou en démarrant une nouvelle instance et en définissant le chemin du dossier actif en haut à gauche de la fenêtre à l’emplacement du fichier de trace.

Setting the folder path in Perfview

Sélectionnez ensuite le fichier de trace dans le volet gauche et ouvrez-le en choisissant Ouvrir dans le menu contextuel ou clic droit.

Remarque

Par défaut, PerfView génère une archive Zip. Lorsque vous ouvrez trace.zip, il décompose automatiquement l’archive et ouvre la trace. Vous pouvez ignorer cette opération en un case activée ing de la zone Zip pendant la collection de traces. Toutefois, si vous envisagez de transférer et d’utiliser des traces sur différents ordinateurs, nous vous recommandons vivement d’annuler case activée la zone Zip. Sans cette option, les fichiers PDB requis pour les assemblys Ngen n’accompagnent pas la trace et les symboles des assemblys Ngen ne seront donc pas résolus sur l’ordinateur de destination. (Consultez ce billet de blog pour plus d’informations sur les PDB pour les assemblys Ngen.)

Le traitement et l’ouverture de la trace peuvent prendre plusieurs minutes. Une fois la trace ouverte, une liste de différentes « vues » apparaît sous celle-ci.

PerfView trace summary view

Nous allons d’abord utiliser la vue Événements pour obtenir l’intervalle de temps du délai d’interface utilisateur :

  1. Ouvrez l’affichage Événements en sélectionnant le nœud sous la trace et en choisissant EventsOuvrir dans le menu contextuel ou cliquez avec le bouton droit.
  2. Sélectionnez «Microsoft-VisualStudio/ExtensionUIUnresponsiveness » dans le volet gauche.
  3. Appuyez sur Entrée

La sélection est appliquée et tous les ExtensionUIUnresponsiveness événements sont affichés dans le volet droit.

Selecting events in Events view

Chaque ligne du volet droit correspond à un délai d’interface utilisateur. L’événement inclut une valeur « ID de délai » qui doit correspondre à l’ID de retard dans le journal d’activité de l’étape 6. Étant ExtensionUIUnresponsiveness donné qu’il est déclenché à la fin du délai de l’interface utilisateur, l’horodatage de l’événement (à peu près) marque l’heure de fin du délai de l’interface utilisateur. L’événement contient également la durée du délai. Nous pouvons soustraire la durée de l’horodatage de fin pour obtenir l’horodatage du début du délai d’interface utilisateur.

Calculating the UI delay time-range

Dans la capture d’écran précédente, par exemple, l’horodatage de l’événement est de 12 125,679 et la durée du délai est de 6 143,085 (ms). Donc

  • Le début du délai est de 12 125,679 - 6 143,085 = 5 982,594.
  • L’intervalle de temps de retard de l’interface utilisateur est de 5 982,594 à 12 125,679.

Une fois que nous avons l’intervalle de temps, nous pouvons fermer l’affichage Événements et ouvrir l’affichage Heure du thread (avec les activités StartStop). Cette vue est particulièrement pratique, car souvent les extensions qui bloquent le thread d’interface utilisateur attendent simplement d’autres threads ou une opération liée aux E/S. Par conséquent, la vue Pile du processeur, qui est l’option d’utilisation pour la plupart des cas, peut ne pas capturer le temps passé par le thread, car il n’utilise pas l’UC pendant ce temps. Les piles de temps de thread résolvent ce problème en affichant correctement l’heure bloquée.

Thread Time (with StartStop Activities) Stacks node in PerfView summary view

Lors de l’ouverture de la vue Piles de temps thread, choisissez le processus devenv pour démarrer l’analyse.

Thread Time Stacks view for UI delay analysis

Dans l’affichage Piles de temps de thread, en haut à gauche de la page, vous pouvez définir l’intervalle de temps sur les valeurs que nous avons calculées à l’étape précédente et appuyer sur Entrée afin que les piles soient ajustées à cet intervalle de temps.

Remarque

Déterminer quel thread est le thread d’interface utilisateur (démarrage) peut être contre-intuitif si la collection de traces est démarrée après que Visual Studio est déjà ouvert. Toutefois, les premiers éléments de la pile du thread d’interface utilisateur (démarrage) sont probablement toujours des DLL du système d’exploitation (ntdll.dll et kernel32.dll) suivies, devenv!? puis msenv!?. Cette séquence peut aider à identifier le thread d’interface utilisateur.

Identifying the startup thread

Vous pouvez également filtrer davantage cette vue en incluant uniquement les piles qui contiennent des modules à partir de votre package.

  • Définissez GroupPats sur texte vide pour supprimer tout regroupement ajouté par défaut.
  • Définissez IncPats pour inclure une partie de votre nom d’assembly en plus du filtre de processus existant. Dans ce cas, il doit être dévenv ; UIDelayR2.

Setting GroupPath and IncPath in Thread Time Stacks view

PerfView contient des instructions détaillées dans le menu Aide que vous pouvez utiliser pour identifier les goulots d’étranglement des performances dans votre code. En outre, les liens suivants fournissent plus d’informations sur l’utilisation des API de thread De Visual Studio pour optimiser votre code :

Vous pouvez également utiliser les nouveaux analyseurs statiques Visual Studio pour les extensions (package NuGet ici), qui fournissent des conseils sur les meilleures pratiques d’écriture d’extensions efficaces. Consultez la liste des analyseurs et des analyseurs de thread de KIT de développement logiciel (SDK) VS.

Remarque

Si vous ne parvenez pas à résoudre la non-réponse en raison de dépendances, vous n’avez pas le contrôle sur (par exemple, si votre extension doit appeler des services VS synchrones sur le thread d’interface utilisateur), nous aimerions en savoir plus. Si vous êtes membre de notre programme Partenaire Visual Studio, vous pouvez nous contacter en envoyant une demande de support aux développeurs. Sinon, utilisez l’outil « Signaler un problème » pour envoyer vos commentaires et inclure "Extension UI Delay Notifications" dans le titre. Incluez également une description détaillée de votre analyse.