Freigeben über


Analysieren von Benutzeroberflächen-Verzögerungen durch Erweiterungen

Wenn die Benutzeroberfläche nicht mehr reagiert, untersucht Visual Studio den Aufrufstapel des UI-Threads, beginnend mit dem Blatt und der Arbeit an der Basis. Wenn Visual Studio feststellt, dass ein Aufrufstapelframe zu einem Modul gehört, das Teil einer installierten und aktivierten Erweiterung ist, wird eine Benachrichtigung angezeigt.

UI delay (unresponsiveness) Notification

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

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

Hinweis

Verwenden Sie die experimentelle Visual Studio-Instanz nicht, um UI-Verzögerungen zu diagnostizieren. Einige Teile der Aufrufstapelanalyse, die für UI-Verzögerungsbenachrichtigungen erforderlich ist, werden bei Verwendung der experimentellen Instanz deaktiviert, was bedeutet, dass Benachrichtigungen zur Benutzeroberflächenverzögerung möglicherweise nicht angezeigt werden.

Eine Übersicht über den Diagnoseprozess ist wie folgt:

  1. Identifizieren Sie das Triggerszenario.
  2. Starten Sie VS mit 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 zuerst ermitteln, was (Abfolge von Aktionen) bewirkt, dass Visual Studio die Benachrichtigung zeigt. Dies ist für Sie in der Lage, die Benachrichtigung später mit aktivierter Protokollierung auszulösen.

Starten Sie VS mit Aktivitätsprotokollierung neu

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, finden 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 einer ETW-Ablaufverfolgung und zum Analysieren. 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 Anbieter "Microsoft-VisualStudio" aktiviert, der vom Anbieter Visual Studio für Ereignisse im Zusammenhang mit Benutzeroberflächenverzögerungsbenachrichtigungen verwendet wird. Außerdem wird der Schlüsselwort (keyword) für den Kernelanbieter angegeben, den PerfView zum Generieren der Threadzeitstapel-Ansicht verwenden kann.

Auslösen der Erneuten Anzeige der Benachrichtigung

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 Ablaufverfolgungssammlung für PerfView beenden, um die Verarbeitung zu verarbeiten und die Ausgabeablaufverfolgungsdatei zu generieren.

Beenden der ETW-Ablaufverfolgung

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

Überprüfen des Aktivitätsprotokolls zum Abrufen der Verzögerungs-ID

Wie Erwähnung weiter oben beschrieben, 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 der Quelle. Dieser Knoten enthält vier Informationen zur Ui-Verzögerung:

  • Die UI-Verzögerungs-ID, eine sequenzielle Zahl, die eine UI-Verzögerung in einer VS-Sitzung eindeutig identifiziert
  • Die Sitzungs-ID, die Ihre Visual Studio-Sitzung vom Anfang bis zum Schließen 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 angezeigten Benachrichtigungswert ü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 als Nächstes 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.

Setting the folder path 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 dekomprimiert und die Spur geöffnet. Sie können dies überspringen, indem Sie das Zip-Feld während der Ablaufverfolgungssammlung deaktivieren. Wenn Sie jedoch planen, Ablaufverfolgungen auf verschiedenen Computern zu übertragen und zu verwenden, wird dringend empfohlen, das Zip-Kontrollkästchen 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.

PerfView trace summary view

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

  1. Öffnen Sie die Ereignisansicht, indem Sie unter der Ablaufverfolgung knoten auswählen Events und im Kontextmenü "Öffnen" auswählen.
  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.

Selecting events in Events view

Jede Zeile im rechten Bereich entspricht einer Ui-Verzögerung. Das Ereignis enthält einen "Delay ID"-Wert, der mit der Verzögerungs-ID im Aktivitätsprotokoll aus Schritt 6 übereinstimmen soll. 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.

Calculating the UI delay time-range

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 Stapelansicht "Threadzeit" (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 kann die CPU-Stapelansicht , die für die meisten Fälle die Option "Go-to" ist, die Zeit, die der Thread blockiert, nicht erfassen, da er die CPU während dieser Zeit nicht verwendet. Die Threadzeitstapel lösen dieses Problem, indem die blockierte Zeit ordnungsgemäß angezeigt wird.

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

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

Thread Time Stacks view for UI delay analysis

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 und kernel32.dll) gefolgt von devenv!? und dann msenv!?. Diese Sequenz kann dabei helfen, den UI-Thread zu identifizieren.

Identifying the startup thread

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 sein ; UIDelayR2.

Setting GroupPath and IncPath in Thread Time Stacks view

PerfView enthält detaillierte Anleitungen im Hilfemenü, 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 VS SDK-Analysegeräte und Threadinganalysatoren finden Sie in einer Liste.

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 in den Titel einzuschließen "Extension UI Delay Notifications" . Bitte geben Sie auch eine detaillierte Beschreibung Ihrer Analyse an.