我正在尝试使用一个Microsoft演示项目,该项目显示how to do ETW event tracing in WPF作为我要开发的应用程序中要进行的某些特定性能分析的基础。
按原样编译,该演示可以正常运行。但是,将目标框架从.Net 3.5更改为.Net 4,它会中断。显然,框架版本之间存在一些重大变化。
问题是发生了什么变化,并且(更重要的是)可以修复该演示吗?
在Debug.WriteLine
上添加FpsEventConsumer.EtwEventCallback
,我发现在框架4中,没有事件到达或两个事件到达,两者都以Header.Guid
中的68fdd900-4a3e-11d1-84f4-0000f80464e3
为单位;一个带有Header.Class.Type
中的UCE_GLASS_START
,另一个带有UCE_GLYPHRUN_START
。请注意,在框架3.5下进行测试时,我还会观察到这些事件以及许多其他事件。
通过在referencesource.microsoft.com上进行的挖掘,我发现MS.Utility.TraceProvider
类型的MS.Utility.EventTrace
's static field EventProvider
控制着发送到ETW的内容。使用反射来访问事件提供程序(由于它是非公开的),因此我发现在3.5中它首先启用了所有内容(_enabled
是true
,_flags
是2147483647
,{ {1}}是_level
);从4开始,所有内容都被禁用(5
为假,_enabled
为_keywords
,而0
为_level
)。但是,通过反思来改变这些价值观似乎并没有太大帮助。充其量,在极少数情况下,我会在上述0
之前发出一些事件。
通过按如下方式在UCE_
中放置WriteLine
,我发现p /被调用的调用继续阻塞,所以问题不在于跟踪被中断了。
TraceConsumer.ProcessTrace
答案 0 :(得分:1)
事实证明,答案一直存在于我所查看的参考源文件之一中:
/// ...
/// TreatAsSafe: it generates the GUID that is passed into the TraceProvider
/// WPF versions prior to 4.0 used provider guid: {a42c77db-874f-422e-9b44-6d89fe2bd3e5}
///</SecurityNote>
[SecurityCritical, SecurityTreatAsSafe]
static EventTrace()
{
Guid providerGuid = new Guid("E13B77A8-14B6-11DE-8069-001B212B5009");
...
以下对Sample.RunTrace
的简单补丁使事件开始流动(尽管它们不再包括演示程序用于FPS的特定事件)。
- m_traceSession = TraceController.WpfController;
+ m_traceSession = typeof(System.Windows.Rect).Assembly.GetName().Version.Major == 3
+ ? TraceController.WpfController
+ : TraceController.GetController(new Guid("E13B77A8-14B6-11DE-8069-001B212B5009"), "WPF");