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=True;
}, 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.
6 comments:
Another solution of this problem is described on http://nmarian.blogspot.com/2007/09/doevents-in-wpf.html
The doevents method should actually be like this:
(*note - the callback should set continue to false!)
static void DoEvents()
{
DispatcherFrame frame = new DispatcherFrame(true);
Dispatcher.CurrentDispatcher.BeginInvoke
(
DispatcherPriority.Background,
(SendOrPostCallback) delegate(object arg)
{
var f = arg as DispatcherFrame;
f.Continue = false;
},
frame
);
Dispatcher.PushFrame(frame);
}
This works just as well btw
System.Windows.Forms.Application.DoEvents()
Just add a reference to System.Windows.Forms
Brilliant! TAMIR!!
Though there are few corrections required, it is a wonderful piece of code. It worked after few corrections. Amazing!! Thanks.
This's my solution.
Application.Current.Dispatcher.Invoke(DispatcherPriority.Background, new System.Threading.ThreadStart(()=>System.Threading.Thread.Sleep(1)));
Can I just say what a relief to search out someone who really is aware of what theyre talking about on the internet. You definitely know how to deliver an issue to mild and make it important. More people need to read this and perceive this aspect of the story. I cant believe youre no more common because you positively have the gift. mgm online casino
Post a Comment