任务并行库使用Windows事件跟踪(ETW)进行日志记录。显然,在Windows Phone或Windows Store .NET Runtime下,TPL或ETW存在与日志记录相关的bug。原始问题在此处描述。
一个可能的解决方法是禁用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();
}
EventListener
添加了IDispose
支持?我不记得3年前看到过 :) - noseratio - open to work