Tuesday, August 21, 2007 4:18 PM
Tamir Khason
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.
תגים:WPF, tutorial, Tips and Tricks