任务并行库使用 Event Tracing for Windows (ETW)用于记录。显然,在 Windows Phone 或 Windows Store .NET Runtime 下,TPL 或 ETW 中存在与日志记录相关的错误。原问题描述here .
一个可能的解决方法是禁用 TPL 的 ETW EventSource
。
如果我真的想要,如何从通用 Windows 应用中禁用它?
反射适用于桌面应用,但不适用于 WP/WinRT 应用。 EventCommand.Disable
未被识别为 EventSource.SendCommand
的有效命令(尽管它在 ETW 内部使用)。这是要使用的代码(作为控制台应用程序):
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
的一部分进行实例化:
public sealed partial class App : Application
{
static MyEventListener listener = new MyEventListener();
}
最佳答案
我遇到了类似的问题并找到了可能的解决方案。
您可以简单地在 EventSource 上调用 Dispose()
!
这不会删除事件源,但会禁用它。它们都继承自的基础 EventSource 确实进行了适当的检查,以防止在禁用时调用继承类的其余部分。所以,理论上,它应该是安全的。但可能有一些 EventSource 实现无法正常工作,因此请彻底测试它!
参见 here对于 EventSource.Dispose(bool disposing)
实现。
关于c# - 如何在通用应用程序中禁用任务并行库的 ETW 事件源?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28472872/