Freigeben über


Analysieren von Benutzeroberflächen-Verzögerungen durch Erweiterungen

Wenn die Benutzeroberfläche nicht mehr reagiert, untersucht Visual Studio den Aufrufstapel des Benutzeroberflächen-Threads, beginnend mit dem Blatt und hin zur Basis. Wenn Visual Studio ermittelt, dass ein Aufrufstapel-Frame zu einem Modul einer installierten und aktivierten Erweiterung gehört, wird eine Benachrichtigung angezeigt.

Benachrichtigung über UI-Verzögerung (nicht reagierend)

Die Benachrichtigung informiert den Benutzer darüber, dass die Benutzeroberflächenverzögerung (d. h. nicht reagierende Benutzeroberfläche) möglicherweise das Ergebnis von Code aus einer Erweiterung war. Außerdem bietet sie dem Benutzer Optionen zum Deaktivieren der Erweiterung oder Aktivieren zukünftiger Benachrichtigungen für diese Erweiterung.

In diesem Dokument wird beschrieben, wie Sie diagnostizieren können, was in Ihrem Erweiterungscode zu Benachrichtigungen über die Benutzeroberflächenverzögerung führt.

Hinweis

Verwenden Sie die experimentelle Visual Studio-Instanz nicht, um UI-Verzögerungen zu diagnostizieren. Einige Teile der für UI-Verzögerungsbenachrichtigungen erforderlichen Aufrufstapelanalyse sind bei Verwendung der experimentellen Instanz deaktiviert, sodass UI-Verzögerungsbenachrichtigungen möglicherweise nicht angezeigt werden.

Eine Übersicht über den Diagnoseprozess:

  1. Identifizieren Sie das Triggerszenario.
  2. Starten Sie VS mit der Aktivitätsprotokollierung neu.
  3. Starten Sie die ETW-Ablaufverfolgung.
  4. Lösen Sie die Benachrichtigung aus, damit sie erneut angezeigt wird.
  5. Beenden Sie die ETW-Ablaufverfolgung.
  6. Überprüfen Sie das Aktivitätsprotokoll, um die Verzögerungs-ID abzurufen.
  7. Analysieren Sie die ETW-Ablaufverfolgung mithilfe der Verzögerungs-ID aus Schritt 6.

In den folgenden Abschnitten werden diese Schritte ausführlicher beschrieben.

Identifizieren des Triggerszenarios

Um eine UI-Verzögerung zu diagnostizieren, müssen Sie zunächst herausfinden, was (Abfolge von Aktionen) dazu führt, dass Visual Studio die Benachrichtigung anzeigt. Dies ist erforderlich, damit Sie die Benachrichtigung später bei aktivierter Protokollierung auslösen können.

Erneutes Starten von VS mit der aktivierter Aktivitätsprotokollierung

Visual Studio kann ein „Aktivitätsprotokoll“ generieren, das beim Debuggen eines Problems hilfreiche Informationen bereitstellt. Um die Aktivitätsprotokollierung in Visual Studio zu aktivieren, öffnen Sie Visual Studio mit der /log-Befehlszeilenoption. Nach dem Starten von Visual Studio wird das Aktivitätsprotokoll am folgenden Speicherort gespeichert:

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

Weitere Informationen dazu, wie Sie Ihre VS-Instanz-ID finden, erhalten Sie unter Tools zum Erkennen und Verwalten von Visual Studio-Instanzen. Wir verwenden dieses Aktivitätsprotokoll später, um weitere Informationen zu UI-Verzögerungen und zugehörigen Benachrichtigungen zu erhalten.

Starten der ETW-Ablaufverfolgung

Sie können PerfView verwenden, um eine ETW-Ablaufverfolgung zu sammeln. PerfView bietet eine benutzerfreundliche Schnittstelle zum Sammeln und Analysieren einer ETW-Ablaufverfolgung. Verwenden Sie den folgenden Befehl, um eine Ablaufverfolgung zu sammeln.

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

Dadurch wird der Microsoft-VisualStudio-Anbieter aktiviert, den Visual Studio für Ereignisse im Zusammenhang mit UI-Verzögerungsbenachrichtigungen verwendet. Außerdem wird das Schlüsselwort für den Kernelanbieter angegeben, den PerfView zum Generieren der Threadzeitstapel-Ansicht verwenden kann.

Lösen Sie die Benachrichtigung aus, damit sie erneut angezeigt wird.

Nachdem PerfView die Ablaufverfolgungsauflistung gestartet hat, können Sie die Triggeraktionssequenz (aus Schritt 1) verwenden, damit die Benachrichtigung erneut angezeigt wird. Sobald die Benachrichtigung angezeigt wird, können Sie die Ablaufverfolgung für die Verarbeitung und Generierung der Ausgabedatei durch PerfView anhalten.

Beenden der ETW-Ablaufverfolgung

Um die Ablaufverfolgungssammlung zu beenden, verwenden Sie einfach die Schaltfläche Sammlung beenden im PerfView-Fenster. Nachdem Sie die Ablaufverfolgungssammlung beendet haben, verarbeitet PerfView automatisch die ETW-Ereignisse und generiert eine Ausgabeablaufverfolgungsdatei.

Überprüfen des Aktivitätsprotokolls, um die Verzögerungs-ID abzurufen

Wie bereits erwähnt, finden Sie das Aktivitätsprotokoll unter %APPDATA%\Microsoft\VisualStudio<vs_instance_id>\ActivityLog.xml. Jedes Mal, wenn Visual Studio eine Erweiterungs-UI-Verzögerung erkennt, schreibt es einen Knoten in das Aktivitätsprotokoll mit UIDelayNotifications als der Quelle. Dieser Knoten enthält vier Informationen zur Ui-Verzögerung:

  • Die UI-Verzögerungs-ID, eine sequenzielle Nummer, die eine UI-Verzögerung in einer VS-Sitzung eindeutig identifiziert
  • Die Sitzungs-ID, die Ihre Visual Studio-Sitzung von Anfang bis Ende eindeutig identifiziert
  • Gibt an, ob eine Benachrichtigung für die UI-Verzögerung angezeigt wurde.
  • Die Erweiterung, die wahrscheinlich zu einer Verzögerung der Benutzeroberfläche führte
<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>

Hinweis

Nicht alle UI-Verzögerungen führen zu einer Benachrichtigung. Daher sollten Sie immer den Wert Benachrichtigung angezeigt? überprüfen, um die richtige UI-Verzögerung korrekt zu identifizieren.

Nachdem Sie die richtige UI-Verzögerung im Aktivitätsprotokoll gefunden haben, notieren Sie sich die im Knoten angegebene UI-Verzögerungs-ID. Sie verwenden die ID, um im nächsten Schritt nach dem entsprechenden ETW-Ereignis zu suchen.

Analysieren der ETW-Ablaufverfolgung

Öffnen Sie dann die Ablaufverfolgungsdatei. Dazu können Sie entweder dieselbe Instanz von PerfView verwenden oder eine neue Instanz starten und den aktuellen Ordnerpfad oben links im Fenster auf den Speicherort der Ablaufverfolgungsdatei festlegen.

Festlegen des Ordnerpfads in Perfview

Wählen Sie dann die Ablaufverfolgungsdatei im linken Bereich aus, und öffnen Sie sie, indem Sie im Kontextmenü Öffnen auswählen.

Hinweis

PerfView gibt standardmäßig ein ZIP-Archiv aus. Wenn Sie trace.zip öffnen, wird das Archiv automatisch entkomprimiert und die Ablaufverfolgung wird geöffnet. Sie können dies überspringen, indem Sie das Feld ZIP während der Ablaufverfolgungssammlung deaktivieren. Wenn Sie jedoch vorhaben, Ablaufverfolgungen auf verschiedene Geräte zu übertragen und zu verwenden, raten wir Ihnen dringend davon ab, das Kontrollkästchen ZIP zu deaktivieren. Ohne diese Option werden die erforderlichen PDBs für Ngen-Assemblys nicht die Ablaufverfolgung begleitet, und daher werden Symbole von Ngen-Assemblys nicht auf dem Zielcomputer aufgelöst. (Weitere Informationen zu PDBs für Ngen-Assemblys finden Sie in diesem Blogbeitrag .)

Es kann mehrere Minuten dauern, bis PerfView die Ablaufverfolgung verarbeitet und geöffnet hat. Sobald die Ablaufverfolgung geöffnet ist, wird eine Liste mit verschiedenen „Ansichten“ unter ihr angezeigt.

Zusammenfassungsansicht der PerfView-Ablaufverfolgung

Wir verwenden zunächst die Ansicht Ereignisse, um den Zeitraum der UI-Verzögerung abzurufen:

  1. Öffnen Sie die Ansicht Ereignisse, indem Sie unter der Ablaufverfolgung den Events-Knoten auswählen und mit einem Rechtsklick oder aus dem Kontextmenü auf Öffnen klicken.
  2. Wählen Sie im linken Bereich Microsoft-VisualStudio/ExtensionUIUnresponsiveness aus.
  3. Drücken Sie die EINGABETASTE.

Die Auswahl wird angewendet, und alle ExtensionUIUnresponsiveness-Ereignisse werden im rechten Bereich angezeigt.

Auswählen von Ereignissen in der Ereignisansicht

Jede Zeile im rechten Bereich entspricht einer UI-Verzögerung. Das Ereignis enthält einen Verzögerungs-ID-Wert, der mit der Verzögerungs-ID im Aktivitätsprotokoll aus Schritt 6 übereinstimmen sollte. Da ExtensionUIUnresponsiveness am Ende der UI-Verzögerung ausgelöst wird, markiert der Zeitstempel des Ereignisses (ungefähr) die Endzeit der UI-Verzögerung. Das Ereignis enthält auch die Dauer der Verzögerung. Wir können die Dauer vom Endzeitstempel subtrahieren, um den Zeitstempel abzurufen, zu dem die UI-Verzögerung gestartet wurde.

Berechnen des UI-Verzögerungszeitbereichs

Im vorherigen Screenshot ist beispielsweise der Zeitstempel des Ereignisses 12.125.679 und die Verzögerungsdauer beträgt 6.143.085 (ms). Demnach sind

  • Der Verzögerungsbeginn beträgt 12.125.679-6.143.085=5.982.594.
  • Der Zeitbereich der Ui-Verzögerung beträgt 5.982.594 bis 12.125.679.

Sobald wir den Zeitraum haben, können wir die Ansicht Ereignisse schließen und die AnsichtThreadzeit-Stapel (mit StartStop-Aktivitäten) öffnen. Diese Ansicht ist besonders praktisch, da häufig Erweiterungen, die den UI-Thread blockieren, nur auf andere Threads oder einen E/A-gebundenen Vorgang warten. Daher erfasst die Ansicht CPU-Stapel, die in den meisten Fällen die erste Wahl ist, möglicherweise nicht die Zeit, die der Thread mit Blockieren verbringt, da er während dieser Zeit die CPU nicht nutzt. Die Ansicht Threadzeitstapel löst dieses Problem, indem die blockierte Zeit ordnungsgemäß angezeigt wird.

Knoten „Threadzeitstapel (mit StartStop-Aktivitäten)“ in der PerfView-Zusammenfassungsansicht

Wählen Sie beim Öffnen der Ansicht Threadzeitstapel den devenv-Prozess aus, um die Analyse zu starten.

Threadzeitstapel-Ansicht für die Analyse der UI-Verzögerung

In der Ansicht Threadzeitstapel können Sie oben links auf der Seite den Zeitbereich auf die Werte festlegen, die wir im vorherigen Schritt berechnet haben, und die EINGABETASTE drücken, damit die Stapel an diesen Zeitraum angepasst werden.

Hinweis

Die Ermittlung, welcher Thread der UI-Thread (Start) ist, kann kontraintuitiv sein, wenn die Ablaufverfolgungssammlung gestartet wird, nachdem Visual Studio bereits geöffnet wurde. Die ersten Elemente im Stapel des UI-Threads (Start) sind jedoch höchstwahrscheinlich immer Betriebssystem-DLLs (ntdll.dll and kernel32.dll) gefolgt von devenv!? und dann msenv!?. Diese Sequenz kann dabei helfen, den UI-Thread zu identifizieren.

Identifizieren des Startthreads

Sie können diese Ansicht auch weiter filtern, indem Sie nur Stapel einschließen, die Module aus Ihrem Paket enthalten.

  • Legen Sie GroupPats auf leeren Text fest, um standardmäßig hinzugefügte Gruppierungen zu entfernen.
  • Legen Sie IncPats fest, um zusätzlich zum vorhandenen Prozessfilter Einen Teil Ihres Assemblynamens einzuschließen. In diesem Fall sollte es devenv;UIDelayR2 sein.

Festlegen von GroupPath und IncPath in der Ansicht „Threadzeitstapel“

PerfView enthält detaillierte Anleitungen unter Hilfe, mit denen Sie Leistungsengpässe in Ihrem Code identifizieren können. Darüber hinaus bieten die folgenden Links weitere Informationen zur Verwendung von Visual Studio-Threading-APIs zur Optimierung Ihres Codes:

Sie können auch die neuen statischen Visual Studio-Analysegeräte für Erweiterungen (NuGet-Paket hier) verwenden, die Anleitungen zu bewährten Methoden zum Schreiben effizienter Erweiterungen bieten. Eine Liste der VSSDK-Analysatoren und Threadinganalysatoren.

Hinweis

Wenn Sie aufgrund von Abhängigkeiten, über die Sie keine Kontrolle haben, nicht reagieren können (z. B. wenn Ihre Erweiterung synchrone VS-Dienste im UI-Thread aufrufen muss), möchten wir es wissen. Wenn Sie Mitglied unseres Visual Studio-Partnerprogramms sind, können Sie uns kontaktieren, indem Sie eine Supportanfrage für Entwickler übermitteln. Verwenden Sie andernfalls das Tool „Problem melden“, um Ihr Feedback zu übermitteln und "Extension UI Delay Notifications" in den Titel einzuschließen. Bitte geben Sie auch eine detaillierte Beschreibung Ihrer Analyse an.