DCSIMG
How to DoEvents in WPF? - Just code - Tamir Khason
Tuesday, August 21, 2007 4:18 PM Tamir Khason

How to DoEvents in WPF?

[This blog was migrated. You will not be able to comment here.
The new URL of this post is http://khason.net/blog/how-to-doevents-in-wpf/]


From VB 5 (even 4) most advanced developers know little nice void method DoEvents. What is it? This is the great way to perform non-blocking wait. The method releases Windows messages pump, other words, performs execution loop. Why this good? Let's see. Following code (C# 1.1) just hangs until the loop will reach it's final value.

for(int i=0;i<1000;i++)
{
label1.Text = i.ToString();
}

How to force it to show values?

for(int i=0;i<1000;i++)
{
label1.Text = i.ToString();
DoEvents();
}

If you want to test this code and see something, put Thread.Sleep(1000); after label1.text... :) Just in case

But in WPF we have no DoEvents() method in application class? What to do? Well, we know, what Dispatcher is. We also know, that it use DispatcherFrame to pump messages, so, why not create our own DoEvents?

void DoEvents(){
DispatcherFrame f = new DispatcherFrame();
Dispatcher.CurrentDispatcher.BeginInvoke(DispatcherPriority.Background, 
(SendOrPostCallback)delegate(object arg) {
    DispatcherFrame fr =  arg as DispatcherFrame;
    fr.Continue=False;
}, f);
Dispatcher.PushFrame(frame);
}

Now, by using this method, we'll release message pump and make our long asynchronous methods not block dispatcher thread, but still wait for the end of execution. Here the example how to do it.

DispatcherOperation op = Dispatcher.CurrentDispatcher.BeginInvoke(DispatcherPriority.Background,
(DispatcherOperationCallback)delegate {
    //DoSomethingReallyLong
    int res = 1;
    int pre = -1;
    for(int i=0;i<1000;++i) {
     int sum = res + pre;
    pre = res;
    res = sum;
     }
    return res;
},null);

while(op != DispatcherOperationStatus.Completed) {
   DoEvents();
}

Console.WriteLine(op.Result);

That's all, folks.

תגים:, ,

Comments

No Comments