How do I listen to TPL TaskStarted/TaskCompleted ETW events
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:
We start new a live event capturing session using
TraceEventSession
where we pass itTraceEventLevel.Always
to print out all messages (we could narrow this down toTranceEventLevel.Information
, but for the example I chose all).We enable the TplEventSource provider by passing its
Guid
tosession.EnableProvider
.We register a callback to be invoked once
TplEventSource
(which is the event source for TPL, obviously) fires eitherTaskExecute/Start
orTaskExecute/Stop
events (taken from the reference source)We print out once we're inside the event.
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.