3

I'm wondering if there is some technique or method to detect calls in a WPF app that are not using async/await.

The reason I ask is that the WPF app I am working on is stuttering and halting on the screen updates, and I can't seem to track down the source of the calls that are blocking the GUI thread.

I am using VS2012 and VS2013 with the MVVM design pattern.

1

4 Answers 4

8

This doesn't answer your question directly but this will help with identifying when the dispatcher thread is overloaded, the following code uses an event handler around the DispatcherInactive event to calculate how long dispatcher thread has been overloaded (blocked) with work:

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

     Application.Current.MainWindow
        .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 suggest this is only ever used in debug mode, so it would be wrapped in a #if DEBUG block. You don't want this running in production.

1
  • This piece of code is absolutely brilliant. Add it to your code, put a breakpoint on the Debug line, and it will instantly break if the GUI thread is being blocked for too long. I wish I had more votes for this answer.
    – Contango
    Sep 12, 2014 at 9:51
1

I think a performance profiler could help you in this case. I personally recommend ANTS profiler, you can download a trial and test your application with it. It would tell you where a certain period of the execution of your app is spending its time in.

1

Usually it is very easy to find what is blocking the UI. There can be 2 cases - either you are performing an expensive operation on the UI thread, you can test if the thread executing is the UI thread using:

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

Or, you are displaying to many controls and it takes long time to render. Usually the lists cause this when the list is not virtualizing items.

1
  • +1 for noting that a list must virtualize items. This is really important for performance improvements.
    – Contango
    Sep 12, 2014 at 9:56
1

You can subscribe to events of the WPF dispatcher to track down your problem. The UI thread queues work items inside an object called a Dispatcher. The Dispatcher selects work items on a priority basis and runs each one to completion.

To monitor the Dispatcher you can e.g. subscribe to these operations:

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

You find a full list here.

Depending on your problem you might find yourself better of with a commercial profiler but quite often you get good results with just observing the dispatcher queue.

2

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.