EventSource.WriteEventCore(Int32, Int32, EventSource+EventData*) 方法

定義

重要

此 API 不符合 CLS 規範。

使用所提供的事件識別項和事件資料,建立新的 WriteEvent 多載。

protected:
 void WriteEventCore(int eventId, int eventDataCount, System::Diagnostics::Tracing::EventSource::EventData* data);
[System.CLSCompliant(false)]
[System.Security.SecurityCritical]
protected void WriteEventCore (int eventId, int eventDataCount, System.Diagnostics.Tracing.EventSource.EventData* data);
[System.CLSCompliant(false)]
protected void WriteEventCore (int eventId, int eventDataCount, System.Diagnostics.Tracing.EventSource.EventData* data);
[<System.CLSCompliant(false)>]
[<System.Security.SecurityCritical>]
member this.WriteEventCore : int * int * nativeptr<System.Diagnostics.Tracing.EventSource.EventData> -> unit
[<System.CLSCompliant(false)>]
member this.WriteEventCore : int * int * nativeptr<System.Diagnostics.Tracing.EventSource.EventData> -> unit

參數

eventId
Int32

事件識別項。

eventDataCount
Int32

事件資料項目的數目。

data
EventSource.EventData

包含事件資料的結構。

屬性

備註

eventid 應該大於 0 或小於 65535,否則作業中可能會發生錯誤。 如果發生錯誤,如果調試程式附加至進程引發事件,您可以檢查調試程序的輸出數據流,以取得錯誤來源的詳細資訊。 如果您在發生錯誤的事件來源上有 ETW 接聽程式,您也可以在 ETW 事件資料流中尋找報告的錯誤。

這個受保護的方法可讓使用者定義比所提供多載快的新 WriteEvent 多載。 建立新的多載牽涉到不安全的程序代碼。 基本程式是堆疊配置符合承載項目數目的事件數據描述元陣列。 針對每個承載專案,在事件數據數位中設定正確的大小和值。使用初始化陣語件呼叫 WriteEventCore

下列範例示範如何新增可接受四個 WriteEvent 自變數的多載。 例如,如果您有記錄字串和 3 個整數的記錄事件。

[Event(1)]
public void LogTime(string tag, int hour, int minute, int second)
{
    WriteEvent(1, tag, hour, minute, second);
}

您可以在不呼叫 WriteEventCore的情況下執行此動作,但速度會比需要慢。 這是因為它會使用陣列和反映來找出該怎麼做。 如果您以高比率 (> 1000 / 秒) 記錄這些檔案,則值得快速協助程式,如下列範例所示。 方法會遮蔽現有的 WriteEvent。 因此,原始呼叫端程式代碼 (LogTime) 實際上不會變更,但 C# 編譯程式會使用更快速的特製化版本。

若要編譯不安全的程式代碼,您必須指定 /unsafe (C# 編譯程式選項) 編譯程序選項。

class AnotherEventSource : EventSource {

    [NonEvent]
    public unsafe void WriteEvent(int eventId, string arg1, int arg2, int arg3, int arg4)
    {

        fixed (char* arg1Ptr = arg1)
        {
            EventData* dataDesc = stackalloc EventData[4];

            dataDesc[0].DataPointer = (IntPtr)arg1Ptr;
            dataDesc[0].Size = (arg1.Length + 1) * 2; // Size in bytes, including a null terminator.
            dataDesc[1].DataPointer = (IntPtr)(&arg2);
            dataDesc[1].Size = 4;
            dataDesc[2].DataPointer = (IntPtr)(&arg3);
            dataDesc[2].Size = 4;
            dataDesc[3].DataPointer = (IntPtr)(&arg4);
            dataDesc[3].Size = 4;

            WriteEventCore(eventId, 4, dataDesc);
        }
    }
}

這些是標準可串行化類型的預期大小和資料編碼:

// bool arg
int temp = arg ? 1 : 0;
desc.DataPointer = (IntPtr)(&temp);
desc.Size = 4;

// byte arg
desc.DataPointer = (IntPtr)(&arg);
desc.Size = 1;

// sbyte arg
desc.DataPointer = (IntPtr)(&arg);
desc.Size = 1;

// char arg
desc.DataPointer = (IntPtr)(&arg);
desc.Size = 2;

// short arg
desc.DataPointer = (IntPtr)(&arg);
desc.Size = 2;

// ushort arg
desc.DataPointer = (IntPtr)(&arg);
desc.Size = 2;

// int arg
desc.DataPointer = (IntPtr)(&arg);
desc.Size = 4;

// uint arg
desc.DataPointer = (IntPtr)(&arg);
desc.Size = 4;

// long arg
desc.DataPointer = (IntPtr)(&arg);
desc.Size = 8;

// ulong arg
desc.DataPointer = (IntPtr)(&arg);
desc.Size = 8;

// float arg
desc.DataPointer = (IntPtr)(&arg);
desc.Size = 4;

// double arg
desc.DataPointer = (IntPtr)(&arg);
desc.Size = 8;

// decimal arg
desc.DataPointer = (IntPtr)(&arg);
desc.Size = 16;

// Guid arg
desc.DataPointer = (IntPtr)(&arg);
desc.Size = 16;

// IntPtr arg
desc.DataPointer = (IntPtr)(&arg);
desc.Size = IntPtr.Size;

// UIntPtr arg
desc.DataPointer = (IntPtr)(&arg);
desc.Size = UIntPtr.Size;

// DateTime arg
long fileTime = arg.ToUniversalTime() > new DateTime(1601, 1, 1) ? arg.ToFileTimeUtc() : 0;
desc.DataPointer = (IntPtr)(&fileTime);
desc.Size = 8;

// string arg
fixed(char* ptr = arg)
{
    desc.DataPointer = (IntPtr)ptr;
    // strings use 2 byte per char UTF16 encoding and a null terminator at the end
    // only strings without embedded null characters are supported
    desc.Size = (arg.Length + 1) * 2;
}

// byte[] arg
// This one is encoded using two adjacent EventData elements.
fixed(byte* ptr = arg)
{
    int length = arg.Length;
    desc[i].DataPointer = (IntPtr)(&length);
    desc[i].Size = 4;
    desc[i + 1].DataPointer = (IntPtr)ptr;
    desc[i + 1].Size = arg.Length;
}

// enums should be converted to their underlying type and then serialized
// as byte, short, or int.

適用於