Dispatcher.CurrentDispatcher与Application.Current.Dispatcher


78

Dispatcher.CurrentDispatcher(in System.Windows.Threading)和Application.Current.Dispatcher(in System.Windows)之间有什么区别?

我的直觉告诉我,它Application.Current.Dispatcher永远不会改变,并且对当前应用程序中的所有线程都是全局的,同时Dispatcher.CurrentDispatcher可能会Dispatcher根据调用它的线程来创建新实例。

那是对的吗?

如果是这样,Dispatcher.CurrentDispatcher主要是为了多线程UI?

Answers:


98

我的直觉告诉我Application.Current.Dispatcher永远不会改变,并且对于当前应用程序中的所有线程都是全局的,而Dispatcher.CurrentDispatcher可能会根据调用它的线程来创建Dispatcher的新实例。

那是正确的。

此外,Dispatcher.CurrentDispatcher从非UI线程进行访问毫无意义。除非您调用Dispatcher.Run,否则它将不会执行任何操作,并且进入无限消息循环不是您希望在工作线程中执行的操作。

所以:

  • 在最常见的情况下,您的应用程序只有一个UI线程,Application.Current.Dispatcher并且Dispatcher.CurrentDispatcher从UI线程内部将返回相同的实例。您使用哪一个只是一个偏好问题。

  • 如果您的应用程序具有多个UI线程,则每个线程都DispatcherObject将与在构造时创建的UI线程的调度程序永久关联。在这种情况下,Application.Current.Dispatcher将引用您的应用程序所产生的线程的调度程序;您将无法使用它将消息发布到其他UI线程所拥有的控件。


2
感谢您的解释,但是“除非您调用Dispatcher.Run,​​否则它将什么都不做”是什么意思?我从非UI线程使用了CurrentDispatcher,并且Invoke确实调用了一个委托。您是说将仅在调用线程上调用委托吗?
2012年

2
@ken:Invoke和朋友通常将方法调用“打包”(如果需要,请打包)到Win32消息中,然后将其发布到消息队列中,消息循环(调度程序循环)最终从该消息队列中提取并执行该调用。由于没有调度程序循环(如果您处于该循环中,则您的代码将不会运行),该调用实际上不会发生。因此,我假设Invoke首先检查您是否已经在CurrentDispatcher线程中作为优化,并且是否在现场执行调用而不是编组。您可以通过选中进行验证Thread.ManagedThreadId
2012年

您将无法使用它将消息发布到其他UI线程所拥有的控件。 那么,您的平均WPF应用程序中有多少个UI线程?

@Will:一个:“如果您的应用程序只有一个UI线程(很可能)...”。您是否需要进一步澄清?
2014年

1
@Will:已编辑以增加相关部分的可见性。谢谢你让我知道。
2014年

21

简而言之...

Dispatcher.CurrentDispatcher获取当前线程的调度程序。因此,如果您要从后台进程中查找UI线程的Dispatcher,请不要使用它。

Application.Current.Dispatcher 将始终为您提供UI线程的调度程序,因为这是唯一的Application实例的启动线程。


9

我的直觉告诉我Application.Current.Dispatcher永远不会改变,并且对于当前应用程序中的所有线程都是全局的,而Dispatcher.CurrentDispatcher可能会根据调用它的线程来创建Dispatcher的新实例。

没错,这Application.Current.Dispatcher是应用程序的实例属性,在构造时将其分配为当前线程的调度程序。并且作为文档Dispatcher.CurrentDispatcher指出:

获取当前正在执行的线程的Dispatcher,如果尚未与该线程关联,则创建一个新的Dispatcher。


如果是,那么Dispatcher.CurrentDispatcher的目的主要是针对多线程UI?

可能地,我在获取后台线程的分派器时没有遇到任何用处,因为您通常没有属于您的UI元素,您可能希望向其分配操作。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.