Partilhar via


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

Definição

Importante

Esta API não está em conformidade com CLS.

Cria uma nova sobrecarga WriteEvent usando o identificador de evento fornecidos e os dados de evento.

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

O identificador de evento.

eventDataCount
Int32

O número de itens de dados de evento.

data
EventSource.EventData

A estrutura que contém os dados do evento.

Atributos

Comentários

eventid deve ser maior que 0 ou menor que 65535 ou erros podem ocorrer na operação. Se ocorrerem erros, você poderá obter mais informações sobre a origem do erro verificando o fluxo de saída do depurador, se você tiver um depurador anexado aos eventos de disparo do processo. Você também pode procurar erros relatados no fluxo de eventos etw, se você tiver um ouvinte ETW na origem do evento em que o erro ocorre.

Esse método protegido permite que os usuários definam novas WriteEvent sobrecargas mais rápidas do que as sobrecargas fornecidas. A criação de uma nova sobrecarga envolve código não seguro. O procedimento básico é alocar uma matriz de descritores de dados de evento que corresponda ao número de itens de carga. Para cada item de conteúdo, defina o tamanho e o valor corretos na matriz de dados do evento. Chame WriteEventCore com a matriz inicializada.

O exemplo a seguir mostra como adicionar uma WriteEvent sobrecarga que aceita quatro argumentos. Um exemplo seria se você tivesse um evento de log que registra uma cadeia de caracteres e três inteiros.

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

Você poderia fazer isso sem chamar WriteEventCore, mas seria mais lento do que precisa ser. Isso ocorre porque ele usa matrizes e reflexão para descobrir o que fazer. Se você registrá-los em uma taxa alta (> 1000/s), pode valer a pena criar um auxiliar rápido, conforme mostrado no exemplo a seguir. O método sombreia o existente WriteEvent. Portanto, o código de chamador original (LogTime) não é realmente alterado, mas o compilador C# usará a versão mais especializada que será mais rápida.

Para compilar código não seguro, você deve especificar a opção do compilador /unsafe (Opções do Compilador 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);
        }
    }
}

Estes são os tamanhos esperados e as codificações de dados para tipos serializáveis padrão:

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

Aplica-se a