Click here to Skip to main content
Click here to Skip to main content

DispatcherFrame. Look in-Depth

, 31 Jan 2011
Rate this:
Please Sign up or sign in to vote.
DispatcherFrame. Look in-Depth

Introduction

Have you ever wondered what exactly DispatcherFrame is? This article will explain it to you.

DispatcherFrame. Look in-Depth

I think that almost all of you heard about DispatcherFrame. Let’s try to understand what is it and where it can be used? MSDN said: “Represent an execution loop in the Dispatcher”. Not enough information to understand and use it as I think. Also, there is an example of a very useful procedure, but also, not obvious to understand. Here it is:

[SecurityPermissionAttribute(SecurityAction.Demand, 
	Flags = SecurityPermissionFlag.UnmanagedCode)]
public void DoEvents()
{   
  DispatcherFrame frame = new DispatcherFrame();   
  Dispatcher.CurrentDispatcher.BeginInvoke(DispatcherPriority.Background,    
     new DispatcherOperationCallback(ExitFrame),
  frame);   
  Dispatcher.PushFrame(frame);
}
 
public object ExitFrame(object f)
{
  ((DispatcherFrame)f).Continue = false;
  return null;
} 

This procedure is DoEvents. As you can guess from its title – it forces events to be performed. So, let’s understand DispatcherFrame and how this method works.

Let’s start with the Dispatcher class. I think everybody who works with WPF knows what it is. It is a class that works with UI thread in WPF. It contains a queue of items that should be performed. I hope that everybody knows about Dispatcher and I don’t need to describe it in detail.

To understand how Dispatcher works, I use ildasm.exe utility to disassemble WindowsBase assembly. I found Dispatcher class and look at its IL. There is a method Run() which starts the Dispatcher work. Let’s look inside this method:

IL_0000:newobj
instance void System.Windows.Threading.DispatcherFrame ::.ctor()
IL_0005:call
void System.Windows.Threading.Dispatcher::PushFrame
	(class System.Windows.Threading.DispatcherFrame)  

New DispatcherFrame is created and PushFrame() method is called. Let’s go to the implementation of this method (I include here only the important lines):

IL_0039:ldarg.0
IL_0043:call
  instance bool System.Windows.Threading.Dispatcher::GetMessage(valuetype
  System.Windows.Interop.MSG&, int, int32, int32)
 
IL_004d:
call instance void
  System.Windows.Threading.Dispatcher::TranslateAndDispatchMessage(valuetype
  System.Windows.Interop.MSG&)
 
IL_0053:
  callvirt instance bool System.Windows.Threading.DispatcherFrame::get_Continue()
IL_0058: 
  brtrue.s IL_0039 

In a friendly manner, it looks like:

While (dispatcherFrame.Continue)
{
  Dispatcher.GetMessage();
  Dispatcher.TranslateAndDispatch();
}

So, while dispatcherFrame’s Continue property is true, this cycle of reading system messages will be executed.

Let’s return to the MSDN definition: “Represent an execution loop in the Dispatcher”. Exactly this WHILE statement is represented by DispatcherFrame.

When the application is started, Dispatcher.Run() is called. Dispatcher creates a default DispatcherFrame which represents the main message loop in application. You can call Dispatcher.PushFrame(DispatcherFrame frame) to start a new loop described above. Main loop will be “paused” until new DispatcherFrame.Continue = false.

Now, let's return to DoEvents() for WPF.

[SecurityPermissionAttribute(SecurityAction.Demand,
Flags = SecurityPermissionFlag.UnmanagedCode)]
public void DoEvents()
{
  DispatcherFrame frame = new DispatcherFrame();
  Dispatcher.CurrentDispatcher.BeginInvoke(DispatcherPriority.Background, 
     new DispatcherOperationCallback(ExitFrame), frame);
  Dispatcher.PushFrame(frame);
}
 
public object ExitFrame(object f)
{
  ((DispatcherFrame)f).Continue = false;
  return null;
}  

Let’s skip the security attribute and go forward. Say, we have a very huge set of operations that should be performed in UI thread and while this application GUI should be updated. Since our operations are performed in UI thread, GUI will not be updated because Dispatcher will be busy by these operations.

How Can This Problem be Solved?

In DoEvents(), there is created new DispatcherFrame (frame variable) and one “Invoke” for dispatcher with Background priority, which sets that frame shouldn’t be continued (frame.Continue=false). Background priority is lowest.

When you call DoEvents(), there is a set of items in Dispatcher that should be performed. Also, this set contains an item which should update our GUI and should be performed ASAP. When PushFrame() is called, the main loop is suspended and a new loop starts (as described above). Dispatcher begins to get system messages AND to process items queue depending on its priority. Dispatcher will process all items and one of those items is operation that stops our new loop. It has the lowest priority and will be performed last. After the operation is invoked, new loop is stopped and the flow returns to the main loop and huge operations processing.

History

  • 31st January, 2011: Initial post

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Renat Khabibulin
Software Developer (Senior) Luxoft
Russian Federation Russian Federation
My developers career starts in 1995, when my father bought my first PC and gave my book "QBasic".
Than it was Pascal, Delphi, C++ Builder...But when I began to work with .Net in 2008, I understand, that this technology is exactly what I need Smile | :)
 
For now, I am a Senior .Net developer at Luxoft.
 
P.S. Right now I am extremly looking for a legal job offer from USA.

Comments and Discussions

 
GeneralMy vote of 1 Pinmemberilia.broudno15-May-14 8:16 
QuestionGood article Pinmemberposaunehm1-Jun-13 6:31 
QuestionGood Article PinmemberFatCat_Programmer13-Feb-12 12:15 
GeneralMy vote of 3 PinmemberPaulo Zemek31-Jan-11 2:25 
AnswerRe: My vote of 3 PinmemberRenatK31-Jan-11 4:42 
GeneralRe: My vote of 3 PinmemberPaulo Zemek31-Jan-11 5:01 
GeneralI think this is pretty good description of DoEvents for WPF PinmvpSacha Barber31-Jan-11 1:58 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web01 | 2.8.140721.1 | Last Updated 31 Jan 2011
Article Copyright 2011 by Renat Khabibulin
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid