Search code examples
.net.net-5perfview

How to get BLOCKED_TIME metric with dotnet-trace


Let's consider a simple case - I'm running a .net5 console app on Windows. If I grab traces via PerfView /threadTime collect like described in here then I get to see BLOCKED_TIME metric in Thread Time Stacks tab. How should I run dotnet-trace command to get the same metric in Perfview? I've tried to play with the verbosity level but no luck so far.


Solution

  • In short, you can't :(

    Dotnet-trace uses a sampling profiler implemented in the .NET runtime. The profiler runs in a separate thread in the application and collects call stack frames of managed threads every few milliseconds. In contrary to most CPU profilers, it collects call stacks even for threads that are waiting. So, by looking at call stacks, you could estimate the waiting time for a managed thread. For example, in the picture below, we may see a managed thread waiting for about 686 ms on a ManualResetEvent.

    enter image description here

    Of course, this is only an estimate and depends on the sampling interval. You may also enable the CLR ThreadPool events and/or the TplEventSource provider to get events describing the inner-working of the thread pool and TPL.

    Now, for the BLOCKED_TIME metric in PerfView. It is based on Context Switch ETW events. You enable them with the 'Thread Time' checkbox in the PerfView collection dialog:

    enter image description here

    These events are emitted by the system scheduler/dispatcher when a new thread starts running on a CPU. They allow us to measure threads' waiting/running times accurately, but they are also very voluminous.