ETW双会话重复接收RundownStart/Start事件问题咨询
ETW双会话导致重复接收RundownStart/Start事件的问题分析
问题描述
创建两个独立的TraceEventSession,一个用于实时输出事件到控制台,另一个用于将事件写入ETL文件,均订阅USB4提供者(GUID: AE795D36-2B11-5EFB-C7E0-5D552BC55D6C),运行时发现RundownStart/Start事件被重复接收两次,仅使用单个会话时无此问题。
代码示例:
var s = new TraceEventSession("mySession", TraceEventSessionOptions.NoPerProcessorBuffering); var s2 = new TraceEventSession($"mySession-log", @"C:\mySession.etl", TraceEventSessionOptions.NoPerProcessorBuffering); var PROVIDER_GUID = new Guid("AE795D36-2B11-5EFB-C7E0-5D552BC55D6C"); var dynamicTraceEventParser = s.Source.Dynamic; dynamicTraceEventParser.All += delegate (TraceEvent data) { Console.WriteLine($"Received DRD event: {data.EventName}"); }; s.EnableProvider(PROVIDER_GUID); s2.EnableProvider(PROVIDER_GUID); s.Source.Process();
原因说明
两个会话本身是独立的,但当同一个ETW提供者被多个会话启用时,会为每个活跃会话单独发送Rundown类事件。RundownStart这类事件的作用是在提供者被启用时,主动发送当前系统状态的快照,每启用一次提供者就会触发一次快照发送,因此两个会话会导致提供者发送两次相同的RundownStart/Start事件。
而普通动态事件(非Rundown类)仅在系统发生对应动作时发送,不会因多会话重复触发。
解决方案
1. 合并会话职责
用单个会话同时实现实时输出和文件记录,避免重复触发提供者的Rundown事件:
// 单个会话同时记录到ETL文件并处理实时事件 var session = new TraceEventSession("myCombinedSession", @"C:\mySession.etl", TraceEventSessionOptions.NoPerProcessorBuffering); var PROVIDER_GUID = new Guid("AE795D36-2B11-5EFB-C7E0-5D552BC55D6C"); session.Source.Dynamic.All += delegate (TraceEvent data) { Console.WriteLine($"Received DRD event: {data.EventName}"); }; session.EnableProvider(PROVIDER_GUID); session.Source.Process();
2. 过滤重复事件
如果必须保留两个独立会话,可通过事件的SessionId属性过滤,只处理当前会话的事件:
dynamicTraceEventParser.All += delegate (TraceEvent data) { // 仅处理来自会话s的事件,忽略会话s2的事件 if (data.SessionId == s.SessionId) { Console.WriteLine($"Received DRD event: {data.EventName}"); } };
3. 延迟启用第二个会话
先启动第一个会话完成Rundown阶段后,再启用第二个会话,但此方式可能错过部分初始事件,仅适用于对初始快照要求不高的场景。
内容的提问来源于stack exchange,提问作者R.P
相关产品推荐
相关产品推荐

