Ereignisanzeige

Im Leistungs-Profiler können Sie während der Ausführung Ihrer App Diagnoseinformationen sammeln und die gesammelten Informationen überprüfen, nachdem die App angehalten wurde (eine Post-Mortem-Analyse).

Die generische Ereignisanzeige zeigt die App-Aktivität anhand einer Liste von Ereignissen wie Laden von Modulen, Starten von Threads und die Systemkonfiguration an. Mit dieser Ansicht können Sie besser diagnostizieren, wie sich Ihre App innerhalb des Visual Studio-Profilers verhält.

Setup

  1. Öffnen Sie über ALT+F2 den Leistungs-Profiler in Visual Studio.

  2. Aktivieren Sie das Kontrollkästchen Ereignisanzeige.

    The Events Viewer check box selected

  3. Klicken Sie auf die Schaltfläche Start, um das Tool auszuführen.

  4. Gehen Sie nach dem Start des Tools das Szenario durch, für das Sie in Ihrer App ein Profil erstellen möchten. Klicken Sie dann auf Sammlung beenden, oder schließen Sie Ihre App, um die Daten anzuzeigen.

    A window showing Stop collection

Weitere Informationen zur Optimierung des Tools finden Sie unter Optimieren der Profilereinstellungen.

Erläuterungen zu den Daten

An event viewer trace

Spaltenname Beschreibung
Anbietername Die Ereignisquelle
Ereignisname Das Ereignis, wie von seinem Anbieter angegeben
Text Beschreibung des Anbieters, Name und ID des Ereignisses
Zeitstempel (ms) Zeitpunkt des Ereignisses
Anbieter-GUID Die ID des Ereignisanbieters
Ereignis-ID Die ID des Ereignisses
Prozess-ID Der Prozess, in dem das Ereignis aufgetreten ist (falls bekannt)
Prozessname Der Name des Prozesses, der aktiv ausgeführt wird
Thread-ID Die ID des Threads, in dem das Ereignis aufgetreten ist (falls bekannt)

Wenn eine Spalte standardmäßig fehlt, klicken Sie mit der rechten Maustaste auf eine der vorhandenen Spaltenüberschriften, und wählen Sie die Spalte aus, die Sie hinzufügen möchten.

Adding columns to the event viewer

Wenn Sie ein Ereignis auswählen, wird das Fenster Zusätzliche Eigenschaften angezeigt. Allgemeine Eigenschaften enthält eine Liste der Eigenschaften, die für ein beliebiges Ereignis angezeigt werden. Nutzlasteigenschaften enthält Eigenschaften, die für das Ereignis spezifisch sind. Bei einigen Ereignissen können Sie auch Stapel anzeigen.

The event viewer showing stacks

Organisieren von Daten

Alle Spalten mit Ausnahme von Text sind sortierbar.

The event viewer trace

In der Ereignisanzeige werden bis zu 20.000 Ereignisse gleichzeitig angezeigt. Um sich auf die relevanten Ereignisse zu konzentrieren, können Sie die Anzeige der Ereignisse durch Auswählen des Ereignisfilters filtern. Sie können auch sehen, welcher Prozentsatz der Gesamtzahl der Ereignisse bei den einzelnen Anbietern aufgetreten ist, und diese Informationen geben Ihnen eine Aufschlüsselung der Ausführungszeit. Bewegen Sie den Mauszeiger über einen einzelnen Ereignisfilter, um eine QuickInfo aufzurufen, die Folgendes zeigt:

  • Ereignisname
  • Anbieter
  • GUID
  • Prozentsatz der Gesamtanzahl der Ereignisse
  • Ereignisanzahl

The event viewer event filter

Der Anbieterfilter zeigt, welcher Prozentsatz der Gesamtanzahl der Ereignisse bei den einzelnen Anbietern aufgetreten ist. Bewegen Sie den Mauszeiger über einen einzelnen Anbieter, um eine ähnliche QuickInfo mit dem Namen des Anbieters, dem Prozentsatz der Gesamtanzahl der Ereignisse und der Anzahl der Ereignisse anzuzeigen.

The event viewer provider filter

Aktivieren von benutzerdefinierten ETW-Ereignissen

Sie können Ihren Code mit benutzerdefinierten ETW-Ereignissen instrumentieren und diese Ereignisse aktivieren, damit sie in der Ereignisanzeige angezeigt werden. So aktivieren Sie benutzerdefinierte Ereignisse:

  1. Erstellen Sie den benutzerdefinierten Ereigniscode.

    Ein Beispiel für benutzerdefinierten C++-Ereigniscode finden Sie am Ende dieses Abschnitts.

  2. Öffnen Sie den Leistungs-Profiler (ALT+F2), aktivieren Sie die Ereignisanzeige, und wählen Sie dann das Zahnradsymbol für die Einstellungen daneben aus.

    Screenshot of the events viewer settings icon.

  3. Aktivieren Sie im Dialogfeld die erste Zeile unter Zusätzliche Anbieter, und führen Sie dann eine der folgenden Aktionen aus:

    • Legen Sie für nativen benutzerdefinierten Ereigniscode die Anbieter-GUID basierend auf der GUID für den benutzerdefinierten Ereigniscode fest, und lassen Sie das Feld Anbietername leer, oder verwenden Sie dessen Standardwert.

    • Legen Sie für den benutzerdefinierten C#-Ereigniscode denselben Wert für Anbietername fest, den Sie beim Deklarieren des Ereigniscodes verwendet haben. Dieser Name wird im Hintergrund in eine GUID konvertiert. Lassen Sie daher die Anbieter-GUID leer.

      Bei einem nativen benutzerdefinierten Ereignis sollte die Zeile ähnlich wie in der folgenden Abbildung aussehen.

      Screenshot of the events viewer settings.

  4. Klicken Sie auf OK.

    Das benutzerdefinierte Ereignis wird in der Ereignisanzeige angezeigt, wenn Sie eine Diagnoseablaufverfolgung erfassen und öffnen. Die folgende Abbildung zeigt die Anzeige der benutzerdefinierten Ereignisse in der Ereignisanzeige, wobei der Filter so eingestellt ist, dass nur benutzerdefinierte Ereignisse angezeigt werden.

    Screenshot of the events viewer showing custom events.

Hier sehen Sie ein Beispiel für benutzerdefinierten Ereigniscode für C++.

#include <Windows.h>
#include <evntprov.h>
#include <iostream>
#include <thread>

// This GUID must be regenerated so it is unique for your provider
// {7369B7AC-64EB-4618-B6B6-C8442B12E8F2}
GUID customEventProvider = { 0x7369b7ac, 0x64eb, 0x4618, { 0xb6, 0xb6, 0xc8, 0x44, 0x2b, 0x12, 0xe8, 0xf2 } };
REGHANDLE _customEventProviderRegHandle = 0;

// Id, Version, Channel, Level, OpCode, Task, Keyword
const EVENT_DESCRIPTOR CustomEventDescriptor = { 1, 0, 0, 0, 0, 0, 1 };

int main()
{
    // Register the provider
    ULONG res = ::EventRegister(&customEventProvider, nullptr, nullptr, &_customEventProviderRegHandle);
    if (res != ERROR_SUCCESS)
    {
        return res;
    }

    byte data[] = { 0xFF, 0xFF, 0xFF, 0xFF };
    EVENT_DATA_DESCRIPTOR eventData[1];
    ::EventDataDescCreate(&(eventData[0]), &data, sizeof(data));

    for (int i = 0; i < 10; ++i)
    {
        std::this_thread::sleep_for(std::chrono::milliseconds(1000));
        ::EventWrite(_customEventProviderRegHandle, &CustomEventDescriptor, _countof(eventData), eventData);
        std::cout << "Wrote event\n";
    }

    res = ::EventUnregister(_customEventProviderRegHandle);
    if (res != ERROR_SUCCESS)
    {
        return res;
    }

    return 0;
}