EventSource.WriteEventCore(Int32, Int32, EventSource+EventData*) Yöntem

Tanım

Önemli

Bu API, CLS uyumlu değildir.

Sağlanan olay tanımlayıcısını ve olay verilerini kullanarak yeni WriteEvent bir aşırı yükleme oluşturur.

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

Parametreler

eventId
Int32

Olay tanımlayıcısı.

eventDataCount
Int32

Olay veri öğelerinin sayısı.

data
EventSource.EventData

Olay verilerini içeren yapı.

Öznitelikler

Açıklamalar

eventid 0'dan büyük veya 65535'ten küçük olmalıdır veya işlemde hatalar oluşabilir. Hatalar oluşursa, işlem başlatma olaylarına bağlı bir hata ayıklayıcınız varsa hata ayıklayıcının çıkış akışını denetleyerek hatanın kaynağı hakkında daha fazla bilgi edinebilirsiniz. Ayrıca, hatanın oluştuğu olay kaynağında bir ETW dinleyiciniz varsa ETW olay akışında bildirilen hataları da arayabilirsiniz.

Bu korumalı yöntem, kullanıcıların sağlanan aşırı yüklemelerden daha hızlı yeni WriteEvent aşırı yüklemeler tanımlamasını sağlar. Yeni bir aşırı yükleme oluşturmak için güvenli olmayan kod gerekir. Temel yordam, yük öğelerinin sayısıyla eşleşen bir olay veri tanımlayıcıları dizisini yığın halinde ayırmaktır. Her yük öğesi için olay verileri dizisinde doğru boyutu ve değeri ayarlayın. Başlatılan dizi ile çağrısı WriteEventCore .

Aşağıdaki örnekte, dört bağımsız değişken kabul eden bir WriteEvent aşırı yüklemenin nasıl ekleneceği gösterilmektedir. Bir dizeyi ve 3 tamsayıyı günlüğe kaydeden bir günlüğe kaydetme olayınız olması buna örnek olarak gösterilir.

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

Bunu çağrısı WriteEventCoreyapmadan yapabilirsiniz, ancak olması gerekenden daha yavaş olacaktır. Bunun nedeni, ne yapacağını anlamak için dizileri ve yansımayı kullanmasıdır. Bunları yüksek hızda (> 1000 / sn) günlüğe kaydederseniz, aşağıdaki örnekte gösterildiği gibi hızlı bir yardımcı yapmaya değer. yöntemi mevcut WriteEventöğesini gölgeler. Bu nedenle, özgün çağıran kodu (LogTime) aslında değişmez, ancak C# derleyicisi daha hızlı olacak daha özelleştirilmiş sürümü kullanır.

Güvenli olmayan kodu derlemek için /unsafe (C# Derleyici Seçenekleri) derleyici seçeneğini belirtmeniz gerekir.

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);
        }
    }
}

Standart serileştirilebilir türler için beklenen boyutlar ve veri kodlamaları şunlardır:

// 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.

Şunlara uygulanır