如何在通用应用程序中禁用任务并行库的ETW EventSource? [英] How to disable Task Parallel Library's ETW EventSource in a Universal App?
问题描述
任务并行库使用此处中进行了描述.
Task Parallel Library uses Event Tracing for Windows (ETW) for logging. Apparently, there is a bug related to logging, in either TPL or ETW, surfacing under Windows Phone or Windows Store .NET Runtime. The original issue is described here.
可能的解决方法是禁用TPL的ETW EventSource
.
A possible workaround would be to disable the TPL's ETW EventSource
.
如果确实要如何在通用Windows应用程序中禁用它?
Reflection适用于桌面应用程序,但不适用于WP/WinRT应用程序. EventCommand.Disable
无法识别为EventSource.SendCommand
的有效命令(尽管它在ETW内部使用).这是(作为控制台应用程序)可使用的代码:
Reflection works for a Desktop app, but not for a WP/WinRT app. EventCommand.Disable
is not recognized as a valid command for EventSource.SendCommand
(although it's used internally in ETW). Here's the code to play with (as a console app):
using System;
using System.Threading.Tasks;
using System.Diagnostics.Tracing;
using System.Reflection;
namespace ConsoleApplication
{
class Program
{
internal class MyEventListener : EventListener
{
protected override void OnEventSourceCreated(EventSource eventSource)
{
Console.WriteLine(eventSource);
base.OnEventSourceCreated(eventSource);
if (eventSource.Name == "System.Threading.Tasks.TplEventSource")
{
Console.WriteLine("enabled: " + eventSource.IsEnabled());
// trying to disable with EventCommand.Disable: Invalid command
try
{
System.Diagnostics.Tracing.EventSource.SendCommand(
eventSource, EventCommand.Disable,
new System.Collections.Generic.Dictionary<string, string>());
Console.WriteLine("enabled: " + eventSource.IsEnabled());
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
// reflection: doesn't work for Windows Phone/Store apps
try
{
var ti = typeof(EventSource).GetTypeInfo();
var f = ti.GetDeclaredField("m_eventSourceEnabled");
f.SetValue(eventSource, false);
Console.WriteLine("enabled: " + eventSource.IsEnabled());
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
}
protected override void OnEventWritten(EventWrittenEventArgs eventData)
{
Console.WriteLine(eventData);
}
}
static MyEventListener listener = new MyEventListener();
static void Main(string[] args)
{
Task.Delay(1000).Wait();
Console.ReadLine();
}
}
}
对于通用应用,MyEventListener
可以作为Application
的一部分实例化:
For a Universal app, MyEventListener
can just be instantiated as part of Application
:
public sealed partial class App : Application
{
static MyEventListener listener = new MyEventListener();
}
推荐答案
我遇到了类似的问题,并找到了可能的解决方案.
I ran into a similar issue and found a potential solution.
您只需在EventSource上调用Dispose()
!
You can simply call Dispose()
on the EventSource!
这不会删除事件源,但是会禁用它.他们都继承自的基本EventSource确实进行了适当的检查,以防止在禁用继承的类时调用其余的继承类.因此,从理论上讲,它应该是安全的.但是可能有些EventSource实现无法正常工作,因此请对其进行彻底的测试!
This will not remove the event source, but it will disable it. And the base EventSource that they all inherit from does have the proper checks in place to prevent the rest of the inherited class from being called when it is disabled. So, in theory, it should be safe. But there may be some EventSource implementations where this will not work, so test it thoroughly!
对于
这篇关于如何在通用应用程序中禁用任务并行库的ETW EventSource?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!