EventSource.WriteEventCore(Int32, Int32, EventSource+EventData*) Metoda

Definice

Důležité

Toto rozhraní API neodpovídá specifikaci CLS.

Vytvoří nové WriteEvent přetížení pomocí zadaného identifikátoru události a dat události.

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

Parametry

eventId
Int32

Identifikátor události.

eventDataCount
Int32

Počet datových položek událostí

data
EventSource.EventData

Struktura, která obsahuje data události.

Atributy

Poznámky

eventid může být větší než 0 nebo méně než 65535 nebo chyby v operaci. Pokud dojde k chybám, můžete získat další informace o zdroji chyby kontrolou výstupního datového proudu ladicího programu, pokud máte ladicí program připojený k událostem spuštění procesu. Pokud máte naslouchací proces ETW ve zdroji událostí, ve kterém dochází k chybě, můžete také vyhledat chyby hlášené ve streamu událostí pro Windows.

Tato chráněná metoda umožňuje uživatelům definovat nová WriteEvent přetížení, která jsou rychlejší než poskytnutá přetížení. Vytvoření nového přetížení zahrnuje nebezpečný kód. Základním postupem je naskládat pole popisovačů dat událostí, které odpovídají počtu položek datové části. Pro každou položku datové části nastavte správnou velikost a hodnotu v poli dat události. Volání WriteEventCore s inicializovaným polem

Následující příklad ukazuje, jak přidat WriteEvent přetížení, které přijímá čtyři argumenty. Příkladem může být událost protokolování, která protokoluje řetězec a 3 celá čísla.

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

Můžete to udělat bez volání WriteEventCore, ale bude pomalejší, než je potřeba. Je to proto, že pomocí polí a reflexe zjistí, co dělat. Pokud tyto protokoly zapíšete vysokou rychlostí (> 1000 / s), může být vhodné rychle pomoct, jak je znázorněno v následujícím příkladu. Metoda stínuje existující WriteEvent. Původní kód volajícího (LogTime) se tedy ve skutečnosti nezmění, ale kompilátor jazyka C# použije specializovanější verzi, která bude rychlejší.

Chcete-li zkompilovat nebezpečný kód, je nutné zadat možnost kompilátoru /nebezpečný (možnosti kompilátoru 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);  
        }  
    }  
}  

Jedná se o očekávané velikosti a kódování dat pro standardní serializovatelné typy:

// 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.ToFileTimeUtc();
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.

Platí pro