다음을 통해 공유


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.

적용 대상