EventSource.WriteEventCore(Int32, Int32, EventSource+EventData*) 方法
定义
重要
一些信息与预发行产品相关,相应产品在发行之前可能会进行重大修改。 对于此处提供的信息,Microsoft 不作任何明示或暗示的担保。
重要
此 API 不符合 CLS。
通过使用提供的事件标识符和事件数据,创建新的 WriteEvent 重载。
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
参数
- eventId
- Int32
事件标识符。
- eventDataCount
- Int32
事件数据项的数目。
包含事件数据的结构。
- 属性
注解
eventid
应大于 0 或小于 65535,否则操作中可能会出现错误。 如果确实发生错误,可以通过检查调试器的输出流来获取有关错误源的详细信息(如果已将调试器附加到进程触发事件)。 如果发生错误的事件源上有 ETW 侦听器,还可以查找 ETW 事件流中报告的错误。
此受保护的方法使用户能够定义比提供的重载更快的新 WriteEvent 重载。 创建新重载涉及不安全的代码。 基本过程是堆栈分配与有效负载项数匹配的事件数据描述符数组。 对于每个有效负载项,在事件数据数组中设置正确的大小和值。使用初始化的 数组调用 WriteEventCore 。
以下示例演示如何添加接受四个 WriteEvent 参数的重载。 例如,如果有记录字符串和 3 个整数的日志记录事件。
[Event(1)]
public void LogTime(string tag, int hour, int minute, int second)
{
WriteEvent(1, tag, hour, minute, second);
}
可以在不调用 WriteEventCore的情况下执行此操作,但速度会比所需慢。 这是因为它使用数组和反射来找出要执行的操作。 如果以 (1000/秒) 的高速率 > 记录这些日志,则值得创建一个快速帮助程序,如以下示例所示。 方法隐藏现有的 WriteEvent。 因此,LogTime) (原始调用方代码实际上不会更改,但 C# 编译器将使用更专用的版本,这将更快。
若要编译不安全的代码,必须指定 /unsafe (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);
}
}
}
以下是标准可序列化类型的预期大小和数据编码:
// 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.