Partager via


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

Définition

Important

Cette API n’est pas conforme CLS.

Crée une surcharge WriteEvent à l'aide de l'identificateur d'événement et des données d'événement fournis.

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

Paramètres

eventId
Int32

Identificateur de l'événement.

eventDataCount
Int32

Nombre d'éléments de données d'événement.

data
EventSource.EventData

Structure contenant les données d'événement.

Attributs

Remarques

eventid doit être supérieur à 0 ou inférieur à 65535 ou des erreurs peuvent se produire dans l’opération. Si des erreurs se produisent, vous pouvez obtenir plus d’informations sur la source de l’erreur en vérifiant le flux de sortie du débogueur, si vous avez un débogueur attaché aux événements de déclenchement du processus. Vous pouvez également rechercher les erreurs signalées dans le flux d’événements ETW, si vous avez un écouteur ETW sur la source d’événement où l’erreur se produit.

Cette méthode protégée permet aux utilisateurs de définir de nouvelles WriteEvent surcharges plus rapides que les surcharges fournies. La création d’une surcharge implique du code non sécurisé. La procédure de base consiste à allouer par pile un tableau de descripteurs de données d’événement qui correspond au nombre d’éléments de charge utile. Pour chaque élément de charge utile, définissez la taille et la valeur correctes dans le tableau de données d’événement. Appelez WriteEventCore avec le tableau initialisé.

L’exemple suivant montre comment ajouter une WriteEvent surcharge qui accepte quatre arguments. Par exemple, si vous avez un événement de journalisation qui journalise une chaîne et 3 entiers.

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

Vous pouvez le faire sans appeler WriteEventCore, mais il serait plus lent qu’il ne doit l’être. Cela est dû au fait qu’il utilise des tableaux et la réflexion pour déterminer ce qu’il faut faire. Si vous les journalisez à un taux élevé (> 1 000 /s), il peut être utile de créer une assistance rapide, comme indiqué dans l’exemple suivant. La méthode masque l’existant WriteEvent. Ainsi, le code de l’appelant d’origine (LogTime) ne change pas réellement, mais le compilateur C# utilisera la version plus spécialisée qui sera plus rapide.

Pour compiler du code non sécurisé, vous devez spécifier l’option de compilateur /unsafe (options du compilateur 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);
        }
    }
}

Voici les tailles attendues et les encodages de données pour les types sérialisables standard :

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

S’applique à