EventSource.WriteEventCore(Int32, Int32, EventSource+EventData*) Methode
Definition
Wichtig
Einige Informationen beziehen sich auf Vorabversionen, die vor dem Release ggf. grundlegend überarbeitet werden. Microsoft übernimmt hinsichtlich der hier bereitgestellten Informationen keine Gewährleistungen, seien sie ausdrücklich oder konkludent.
Wichtig
Diese API ist nicht CLS-kompatibel.
Erstellt eine neue WriteEvent Überladung mithilfe der bereitgestellten Ereignis-ID und Ereignisdaten.
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)]
[System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("EventSource will serialize the whole object graph. Trimmer will not safely handle this case because properties may be trimmed. This can be suppressed if the object is a primitive type")]
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)>]
[<System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("EventSource will serialize the whole object graph. Trimmer will not safely handle this case because properties may be trimmed. This can be suppressed if the object is a primitive type")>]
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
Parameter
- eventId
- Int32
Der Ereignisbezeichner.
- eventDataCount
- Int32
Die Anzahl der Ereignisdatenelemente.
Die Struktur, die die Ereignisdaten enthält.
- Attribute
Hinweise
eventid sollte größer als 0 oder kleiner als 65535 sein, oder Fehler können im Vorgang auftreten. Wenn Fehler auftreten, können Sie weitere Informationen zur Quelle des Fehlers erhalten, indem Sie den Ausgabedatenstrom des Debuggers überprüfen, wenn ein Debugger an die Prozessauslösungsereignisse angefügt ist. Sie können auch nach Fehlern suchen, die im ETW-Ereignisdatenstrom gemeldet wurden, wenn Sie über einen ETW-Listener in der Ereignisquelle verfügen, in der der Fehler auftritt.
Mit dieser geschützten Methode können Benutzer neue WriteEvent Überladungen definieren, die schneller als die bereitgestellten Überladungen sind. Das Erstellen einer neuen Überladung umfasst unsicheren Code. Die grundlegende Prozedur besteht darin, ein Array von Ereignisdatendeskriptoren zuzuordnen, die der Anzahl der Nutzlastelemente entsprechen. Legen Sie für jedes Nutzlastelement die richtige Größe und den richtigen Wert im Ereignisdatenarray fest. Aufruf WriteEventCore mit dem initialisierten Array.
Das folgende Beispiel zeigt, wie Sie eine WriteEvent Überladung hinzufügen, die vier Argumente akzeptiert. Ein Beispiel wäre, wenn Sie über ein Protokollierungsereignis verfügen, das eine Zeichenfolge und drei ganze Zahlen protokolliert.
[Event(1)]
public void LogTime(string tag, int hour, int minute, int second)
{
WriteEvent(1, tag, hour, minute, second);
}
Sie könnten dies ohne Aufrufe WriteEventCoretun, aber es wäre langsamer als es sein muss. Das liegt daran, dass Arrays und Reflexionen verwendet werden, um herauszufinden, was zu tun ist. Wenn Sie diese mit einer hohen Rate (> 1000 / Sek.) protokollieren, kann es sich lohnen, einen schnellen Helfer zu erstellen, wie im folgenden Beispiel gezeigt. Die Methode schattiert die vorhandene WriteEvent. Daher ändert sich der ursprüngliche Aufrufercode (LogTime) nicht tatsächlich, aber der C#-Compiler verwendet die speziellere Version, die schneller wird.
Um unsicheren Code zu kompilieren, müssen Sie die Compileroption /unsafe (C#-Compileroptionen) angeben.
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);
}
}
}
Dies sind die erwarteten Größen und Datencodierungen für standardmäßig serialisierbare Typen:
// 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.