Click here to Skip to main content
15,881,709 members
Articles / Desktop Programming / WPF

DispatcherFrame. Look in-Depth

Rate me:
Please Sign up or sign in to vote.
4.60/5 (10 votes)
31 Jan 2011CPOL3 min read 48K   15   7
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:

C#
[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:

C#
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):

MSIL
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:

MSIL
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.

C#
[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)


Written By
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 Pin
ilia.broudno15-May-14 8:16
ilia.broudno15-May-14 8:16 
QuestionGood article Pin
posaunehm1-Jun-13 6:31
posaunehm1-Jun-13 6:31 
QuestionGood Article Pin
FatCatProgrammer13-Feb-12 12:15
FatCatProgrammer13-Feb-12 12:15 
GeneralMy vote of 3 Pin
Paulo Zemek31-Jan-11 2:25
mvaPaulo Zemek31-Jan-11 2:25 
AnswerRe: My vote of 3 Pin
Renat Khabibulin31-Jan-11 4:42
Renat Khabibulin31-Jan-11 4:42 
GeneralRe: My vote of 3 Pin
Paulo Zemek31-Jan-11 5:01
mvaPaulo Zemek31-Jan-11 5:01 
GeneralI think this is pretty good description of DoEvents for WPF Pin
Sacha Barber31-Jan-11 1:58
Sacha Barber31-Jan-11 1:58 

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

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