Dispatcher.CurrentDispatcher与Application.Current.Dispatcher的区别

94
Dispatcher.CurrentDispatcher(位于System.Windows.Threading)和Application.Current.Dispatcher(位于System.Windows)之间有什么区别呢?我的理解是Application.Current.Dispatcher不会改变且适用于当前应用程序中的所有线程,而Dispatcher.CurrentDispatcher根据调用它的线程可能会创建一个Dispatcher实例。这个理解正确吗?如果正确,那么Dispatcher.CurrentDispatcher的主要目的是用于多线程UI吗?
3个回答

116

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

这是正确的。

此外,在非UI线程中访问Dispatcher.CurrentDispatcher毫无意义。除非您调用Dispatcher.Run,否则它将不起作用,并且在工作线程内进入无限消息循环不是您想要做的事情。

所以:

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

  • 如果您的应用程序有多个UI线程,则每个DispatcherObject将永久关联于它在构造时创建的UI线程的分派程序。在这种情况下,Application.Current.Dispatcher将引用您的应用程序生成的线程的分派程序;您将无法使用它来向其他UI线程拥有的控件发送消息。


2
谢谢您的解释,但是“除非您调用Dispatcher.Run,否则它将不起作用”是什么意思?我已经从非UI线程使用了CurrentDispatcher,并且Invoke确实会调用委托。您的意思是委托将在调用线程上简单地被调用吗? - ken
3
Invoke和相关方法通常会将一个方法调用“打包”(如果您愿意,也可以称为序列化)为一个Win32消息,并将其发布到消息队列中。最终,消息循环(分派循环)会从消息队列中提取该消息并执行该调用。由于没有分派循环(如果您在该循环中,那么您的代码不会运行),因此调用实际上永远不会发生。因此,我认为Invoke首先检查是否已经在CurrentDispatcher线程中作为一种优化方式,如果是,则立即在该处执行调用,而不进行序列化。您可以通过检查Thread.ManagedThreadId来验证这一点。 - Jon
你将无法使用它来向其他 UI 线程拥有的控件发送消息。那么,在你的平均 WPF 应用程序中有多少个 UI 线程? - user1228
@Will:一:“如果您的应用程序只有一个UI线程(最有可能的情况)……”。你认为它需要更多的澄清吗? - Jon
@Jon:嗯,考虑到它让我感到困惑,是的。我没有看到你引用的那一行... - user1228
1
@Will:编辑以增加相关部分的可见性。感谢您让我知道。 - Jon

28
简单来说... Dispatcher.CurrentDispatcher 获取当前线程的调度程序。因此,如果您正在从后台进程查找 UI 线程的 Dispatcher,请勿使用此选项。 Application.Current.Dispatcher 将始终为您提供 UI 线程的调度程序,因为这是启动唯一 Application 实例的线程。

10
我的直觉告诉我,Application.Current.Dispatcher 不会改变且适用于当前应用程序中的所有线程,而 Dispatcher.CurrentDispatcher 会根据调用它的线程创建一个新的 Dispatcher 实例。
是的,Application.Current.Dispatcher 是应用程序的实例属性,它在构造时被指定为当前线程的分派程序。正如 Dispatcher.CurrentDispatcher 文档所述:
获取当前正在执行的线程的分派程序,并在尚未与该线程关联的情况下创建新的分派程序。
如果是这样,那么 Dispatcher.CurrentDispatcher 的主要目的是否是多线程 UI?
可能是的,我没有遇到过获取后台线程的分派程序的用途,因为通常不存在与其相关的 UI 元素需要进行操作分派。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接