With WPF, is there a method to detect method calls that block GUI updates?

I am wondering if there is any method or method for detecting calls in a WPF application that does not use async / await.

I ask that the WPF application I'm working on stutters and stops on screen updates and I can't keep track of the origin of the calls that are blocking the GUI thread.

I am using VS2012 and VS2013 with MVVM design pattern.


source to share

4 answers

This does not directly answer your question, but it will help you determine when the dispatcher thread is overloaded, the following code uses an event handler around the DispatcherInactive event to calculate how long the dispatcher thread has been overloaded (blocked) with work:

var maxThreshold = TimeSpan.FromMilliseconds(750);
var previous = DateTime.Now;

        .Dispatcher.Hooks.DispatcherInactive += (sender, eventArgs) =>
            var current = DateTime.Now;
            var delta = current - previous;

            previous = current;

            if (delta > maxThreshold)
                Debug.WriteLine("UI Freeze = {0} ms", delta.TotalMilliseconds);


I would assume this is always used in debug mode, so it will be wrapped in a block #if DEBUG

. You don't want this to be done in production.



I think a performance profiler could help you in this case. I personally recommend ANTI profiler , you can download the trial version and test its application. It will tell you where a specific runtime of your application spends its time.



It is usually very easy to find what is blocking the user interface. There can be two cases, either you are performing an expensive operation on the UI thread, you can check if the execution of the thread is on the UI thread using:

if (Thread.CurrentThread == Dispatcher.CurrentDispatcher.Thread)
    //UI Thread


Or you are showing many controls and it takes a long time to render. Typically lists call this when the list is not virtualizing the elements.



You can subscribe to WPF dispatcher events to track your problem. UI thread queues process items inside an object called a dispatcher. The dispatcher selects work items in priority order and runs each one until completion.

To control the Dispatcher, you can, for example, subscribe to these operations:

Dispatcher.Hooks.OperationPosted += Hooks_OperationPosted;
Dispatcher.Hooks.OperationStarted += Hooks_OperationStarted;
Dispatcher.Hooks.OperationAborted += Hooks_OperationAborted;


You will find a complete list here.

Depending on your problem, you may be better off with a commercial profiler, but quite often you get good results just by watching the dispatch queue.



All Articles