次の方法で共有


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

次の例は、4 つの引数を 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.

適用対象