事件檢視器

使用效能分析工具時,您可以在執行應用程式時收集診斷資訊,並在應用程式停止 (像是事後檢討分析) 檢查所收集的資訊。

一般事件檢視器會透過模組載入、執行緒啟動和系統設定等事件清單,來顯示應用程式活動。 此檢視可協助您更妥善地診斷,應用程式在 Visual Studio 分析工具內執行的方式。

設定

  1. 若要在 Visual Studio 中開啟效能分析工具,請選取 Alt+F2

  2. 選取 [事件檢視器] 核取方塊。

    The Events Viewer check box selected

  3. 選取 [開始] 按鈕以執行此工具。

  4. 工具開始執行之後,請瀏覽情節以在應用程式中分析。 然後選取 [停止收集] 或關閉應用程式以查看資料。

    A window showing Stop collection

如需如何讓工具更有效率的詳細資訊,請參閱最佳化分析設定

了解您的資料

An event viewer trace

資料行名稱 描述
Provider Name 事件的來源
事件名稱 由其提供者指定的事件
Text 事件提供者、事件名稱和識別碼的描述
時間戳記 (毫秒) 事件發生時
提供者 GUID 事件提供者的識別碼
事件識別碼 事件的識別碼
Process ID 事件發生的過程 (如果已知)
程序名稱 如果程序正在主動執行,則其名稱
執行緒識別碼 發生事件的執行緒識別碼 (如果已知)

如果預設遺漏任何資料行,請以滑鼠右鍵按一下其中一個現有的資料行標頭,然後選取您要新增的資料行。

Adding columns to the event viewer

當您選取事件時,[其他屬性] 視窗隨即出現。 通用屬性會顯示任何事件都會出現的屬性清單。 承載屬性會顯示事件特有的屬性。 針對某些事件,您也可以檢視堆疊

The event viewer showing stacks

組織資料

Text 資料行以外的所有資料行都可以排序。

The event viewer trace

事件檢視器一次最多顯示 20,000 個事件。 若要專注於感興趣的事件,您可以選取 [事件篩選器] 來篩選顯示的事件。 您也可以查看每個提供者所發生的事件總數百分比,此資訊會提供您所用時間的明細。 將滑鼠停留在單一事件篩選器上,以查看工具提示,其中顯示以下內容:

  • 事件名稱
  • Provider
  • GUID
  • 事件總數的百分比
  • 事件計數

The event viewer event filter

提供者篩選條件會顯示每個提供者所發生事件總數的百分比。 將滑鼠停留在單一提供者上,以查看類似的工具提示,其中包含提供者名稱、事件總數百分比和事件計數。

The event viewer provider filter

啟用自訂 ETW 事件

您可以使用自訂 ETW 事件檢測程式碼,並使其能夠顯示在事件檢視器中。 若要啟用自訂事件:

  1. 建置自訂事件程式碼。

    本節結尾會提供 C++ 自訂事件程式碼的範例。

  2. 開啟 [效能分析工具] (Alt + F2),啟用 [事件檢視器],然後選取其旁邊的 [設定] 圖示 (齒輪圖示)。

    Screenshot of the events viewer settings icon.

  3. 在對話方塊中,啟用 [其他提供者] 底下的第一個資料列,然後採取下列其中一個動作:

    • 針對原生自訂事件程式碼,根據自訂事件程式碼的 GUID 設定 [提供者 GUID],並將 [提供者名稱] 保留空白,或使用其預設值。

    • 針對 C# 自訂事件程式碼,請設定您在宣告事件程式碼時所使用的相同 [提供者名稱] 值。 此名稱會轉換成背景中的 GUID,因此請將 [提供者 GUID] 保留空白。

      對於原生自訂事件,資料列外觀應與下圖類似。

      Screenshot of the events viewer settings.

  4. 選取 [確定]。

    當您收集診斷追蹤並加以開啟時,自訂事件會出現在 [事件檢視器] 中。 下圖顯示事件檢視器中的自訂事件,而該檢視器的篩選設定為只顯示自訂事件。

    Screenshot of the events viewer showing custom events.

以下是 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;
}