我怎么听TPL TaskStarted / TaskCompleted ETW事件 [英] How do I listen to TPL TaskStarted/TaskCompleted ETW events

查看:273
本文介绍了我怎么听TPL TaskStarted / TaskCompleted ETW事件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我感兴趣的是听ETW(Windows事件跟踪)TPL的事件,尤其是我想知道当一个工作启动和停止时。

I am interested in listening to ETW (event tracing for Windows) TPL events, in particular I'd like to know when a Task starts and when it stops.

下面是我用于测试的样本程序:

Here's a sample program I've used for testing:

   using System;
   using System.Collections.Generic;
   using System.Diagnostics.Tracing;
   using System.Linq;
   using System.Text;
   using System.Threading;
   using System.Threading.Tasks;

   namespace ConsoleApplication10
   {
      class Listener : EventListener
      {
         private static readonly Guid tplGuid = new Guid("2e5dba47-a3d2-4d16-8ee0-6671ffdcd7b5");

         protected override void OnEventSourceCreated(EventSource eventSource)
         {
            Console.WriteLine("Got guid: " + eventSource.Guid);
            EnableEvents(eventSource, EventLevel.LogAlways);
         }

         protected override void OnEventWritten(EventWrittenEventArgs eventData)
         {
            Console.WriteLine("Event: " + eventData.EventId);
         }
      }

      class Program
      {
         static void Main(string[] args)
         {
            using (var listener = new Listener())
            {
               Action doIt = null;
               doIt = () =>
               {
                  Thread.Sleep(1000);
                  Console.Write('.');
                  Task.Run(doIt);
               };
               Task.Run(doIt);

               Parallel.Invoke(() => Console.WriteLine("invoke"));

               Console.Read();
            }
         }
      }
   }



样品输出是在我的机器上进行如下:

Sample output is as follows on my machine:

Got guid: 8e9f5090-2d75-4d03-8a81-e5afbf85daf1
Got guid: 2e5dba47-a3d2-4d16-8ee0-6671ffdcd7b5
Event: 3
invoke
Event: 4
.......

所以Invoke方法会导致事件激发,但任务没有开火。纵观任务源(如参考源)的代码出现无异于如何使用 Parallel.Invoke 事件触发不同的。

So the Invoke method causes an event to fire, yet the Tasks fire none. Looking at the Task source (e.g. reference source) the code appears no different from how the Parallel.Invoke event fires.

什么是错误的上述情况,或,我怎么听TaskStarted和TaskCompleted事件(或任何与此有关的的任务相关的事件)?

What is wrong with the above, or, how do I listen to TaskStarted and TaskCompleted events (or any Task related event for that matter)?

推荐答案

您的问题challanged我寻找到ETW(这是我一直想寻找到一段时间)。我能捕捉到的任务开始的和的任务的结束的使用的 Microsoft.Diagnostics.Tracing.TraceEvent的NuGet库用简单的下面的代码:

Your question challanged me to look into ETW (which I've been wanting to look into for a while). I was able to capture "task start" and "task end" using Microsoft.Diagnostics.Tracing.TraceEvent NuGet library with the simple following code:

private static void Main(string[] args)
{
    Task.Run(() =>
    {
        using (var session = new TraceEventSession("TplCaptureSession"))
        {
            session.EnableProvider(new Guid("2e5dba47-a3d2-4d16-8ee0-6671ffdcd7b5"),
                                   TraceEventLevel.Always);

            session.Source.Dynamic.AddCallbackForProviderEvent("System.Threading.Tasks
                                                               .TplEventSource",
                "TaskExecute/Start", @event =>
                {
                    Console.WriteLine("Inside Task Started");
                });

            session.Source.Dynamic.AddCallbackForProviderEvent("System.Threading.Tasks
                                                   .TplEventSource", 
                "TaskExecute/Stop", @event =>
                {
                    Console.WriteLine("Inside Task Stopped");
                });

            session.Source.Process();
        }
    });

    var task = Task.Run(async () =>
    {
        await Task.Delay(20000);
    });

    task.Wait();
}



基本上发生的事情是:

Basically what happens is:


  1. 我们开始新的现场活动使用捕捉会话 TraceEventSession 在这里我们把它传递 TraceEventLevel.Always 来打印出所有消息(我们可以缩小这个下来 TranceEventLevel.Information ,但对于例如我选择全部)。

  1. We start new a live event capturing session using TraceEventSession where we pass it TraceEventLevel.Always to print out all messages (we could narrow this down to TranceEventLevel.Information, but for the example I chose all).

我们能够通过传递它的的Guid session.EnableProvider

We enable the TplEventSource provider by passing its Guid to session.EnableProvider.

我们注册一个回调,一旦 TplEventSource (这是事件源TPL,很明显)触发或者 TaskExecute /启动 TaskExecute /停止事件(从的参考源

We register a callback to be invoked once TplEventSource (which is the event source for TPL, obviously) fires either TaskExecute/Start or TaskExecute/Stop events (taken from the reference source)

我们打印出来,一旦我们的事件中。

We print out once we're inside the event.

请注意我用 Task.Run 很简单,因为 session.Source.Process()是一个阻塞调用,我希望它在后台运行。

Note my use of Task.Run was simply because session.Source.Process() is a blocking call, and I wanted it to run in the background.

这篇关于我怎么听TPL TaskStarted / TaskCompleted ETW事件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆