开发者

WPF/threading: Dispatcher static vs Dispatcher on a control?

I'm a bit confused in terms of the dispatcher. Say I'm on a background thread doing some kind of long operation. I'd like to update the ui thread I understand I do this through the dispatcher. My question is, do i call the dispatcher statically like: Dispatcher.BeginInvoke(mywork) ... Or on the control i want to update: mytextbox.Dispat开发者_C百科cher.BeginInvoke(mywork)


It's worth noting that calling Dispatcher.BeginInvoke isn't a static call: it's an implicit this.Dispatcher.BeginInvoke. If you can use this call, you're likely writing your code from within a control or window already. In that case, you're probably safe to call either since most of the time there will be one UI thread per application.

The actual static call would be Dispatcher.CurrentDispatcher.BeginInvoke, which is not something you want to call (see my comment on Hasan Khan's answer for why).

EDIT: Calling Application.Current.Dispatcher is not a bad thing. (And, for clarity, it's an instance property, not a static - being called on a static/singleton instance of Application.) This property will return the Dispatcher for the thread that the app was created with, and typically that's the thread that the UI is created on aswell - so Application.Current.Dispatcher returns the same Dispatcher as myWindow.Dispatcher would.

The static call Dispatcher.CurrentDispatcher (that I warned against) returns a Dispatcher for the thread you call it from. If you call it from a background thread, you'll get a new Dispatcher created especially for that thread - which often isn't what's wanted.


First I think it is important to understand, that the Dispatcher is not designed to handle big background operations. It is designed to queue work on the UI thread of an object. Here is a worthwhile MSDN article about the .NET threading model and Dispatcher:

  • Threading Model, Overview and the Dispatcher

Saying that the standard way of implementing the Dispatcher.BeginInvoke method would be to call it on the control:

startStopButton.Dispatcher.BeginInvoke(
    DispatcherPriority.Normal, new NextPrimeDelegate(CheckNextNumber)
);

Hope that helps!


While in most cases using either DispatcherObject.Dispatcher (all dependency objects and controls inherit from DispatcherObject, among others) or Application.Current.Dispatcher is the right thing to do, as there's usually only one UI thread, there can be multiple UI threads and different windows can use different dispatchers. In that case, it's important to update the control using its dispatcher. It's stored in in its Dispatcher property (inherited from DispatcherObject), any other control in this window and the window itself.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜