EventSource.WriteEventCore(Int32, Int32, EventSource+EventData*) Método

Definición

Importante

Esta API no es conforme a CLS.

Crea una nueva sobrecarga de WriteEvent usando el identificador de eventos y los datos de eventos proporcionados.

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

Parámetros

eventId
Int32

Identificador de evento.

eventDataCount
Int32

El número de elementos de datos de eventos.

data
EventSource.EventData

Estructura que contiene los datos del evento.

Atributos

Comentarios

eventid debe ser mayor que 0 o menor que 65535 o se pueden producir errores en la operación. Si se producen errores, puede obtener más información sobre el origen del error comprobando el flujo de salida del depurador, si tiene un depurador asociado a los eventos de activación del proceso. You can also look for errors reported in the ETW event stream, if you have an ETW listener on the event source where the error occurs.

Este método protegido permite a los usuarios definir nuevas WriteEvent sobrecargas que son más rápidas que las sobrecargas proporcionadas. La creación de una nueva sobrecarga implica código no seguro. El procedimiento básico consiste en apilar una matriz de descriptores de datos de eventos que coincida con el número de elementos de carga. Para cada elemento de carga, establezca el tamaño y el valor correctos en la matriz de datos de eventos. Llame a WriteEventCore con la matriz inicializada.

En el ejemplo siguiente se muestra cómo agregar una WriteEvent sobrecarga que acepta cuatro argumentos. Un ejemplo sería si tiene un evento de registro que registra una cadena y 3 enteros.

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

Podría hacerlo sin llamar a WriteEventCore, pero sería más lento de lo que necesita. Esto se debe a que usa matrices y reflexión para averiguar qué hacer. Si registra estos valores a una velocidad alta (> 1000 por segundo), puede ser útil crear un asistente rápido, como se muestra en el ejemplo siguiente. El método sombrea el objeto existente WriteEvent. Por lo tanto, el código de llamada original (LogTime) no cambia realmente, pero el compilador de C# usará la versión más especializada que será más rápida.

Para compilar código no seguro, debe especificar la opción del compilador /unsafe (Opciones del compilador de 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);
        }
    }
}

Estos son los tamaños esperados y las codificaciones de datos para los tipos serializables estándar:

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

Se aplica a