In WPF due to the intricacies on how the interface is updated I sometimes have to perform actions after a short delay.
Currently I'm doing this simply by:
var dt = new DispatcherTimer(DispatcherPriority.Send);
dt.Tick += (s, e) =>
{
dt.Stop();
//DoStuff
};
dt.Interval = TimeSpan.FromMilliseconds(200);
dt.Start();
But it's both a bit ugly and perhaps too much overhead to create a new timer each time (?) What's the best from a performance standpoint to do it, ie execute most promptly? And what's good way to rewrite the above code into something like:
this.Dispatcher.BeginInvoke(new Action(delegate()
{
//DoStuff
}), DispatcherPriority.Send,TimeSpan.FromMilliseconds(200));
Where Timespan is the delay, Thanks for any input :)
Invoke(Action, DispatcherPriority) Executes the specified Action synchronously at the specified priority on the thread the Dispatcher is associated with. Invoke(Action) Executes the specified Action synchronously on the thread the Dispatcher is associated with.
Invoke is synchronous and BeginInvoke is asynchronous. The operation is added to the event queue of the Dispatcher at the specified DispatcherPriority. If BeginInvoke is called on a Dispatcher that has shut down, the status property of the returned DispatcherOperation is set to Aborted.
The Dispatcher maintains a prioritized queue of work items for a specific thread. When a Dispatcher is created on a thread, it becomes the only Dispatcher that can be associated with the thread, even if the Dispatcher is shut down.
I wouldn't assume that the DispatcherTimer
is heavy-weight... why not just write an extension method on Dispatcher
which allows you to use the syntax you want, and uses a DispatcherTimer
in the background? I would personally call it DelayInvoke
rather than BeginInvoke
though... and I'd also fix it to always use Action
rather than an arbitrary delegate... that will make it easier to use lambda expressions:
Dispatcher.DelayInvoke(TimeSpan.FromMilliseconds(200), () => { ...
});
(I tend to find it's more readable if anonymous functions are used as the final argument in a method call, but that's just a personal preference.)
Given that you'll quite possibly want to use milliseconds most of the time, you could have another helper method too:
Dispatcher.DelayInvokeMillis(200, () => { ...
});
Another alternative to try is merely to use the existing BeginInvoke
method but with a very low priority, so your delegate will only be invoked after everything else has finished. Without knowing the details of your situation, it's hard to know whether that'll work or not - but it's worth trying.
A .NET 4.5 way:
public async void MyMethod()
{
await Task.Delay(20);
await Dispatcher.BeginInvoke((Action)DoStuff);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With