WPF /线程:控件上的Dispatcher static vs Dispatcher?

我在调度员方面有点困惑。 假设我在后台线程上进行某种长时间的操作。 我想通过调度程序更新我理解的ui线程。 我的问题是,我是否静态调用调度程序:Dispatcher.BeginInvoke(mywork)…或者我想要更新的控件:mytextbox.Dispatcher.BeginInvoke(mywork)

值得注意的是,调用Dispatcher.BeginInvoke 不是静态调用:它是一个隐式this.Dispatcher.BeginInvoke 。 如果您可以使用此调用,则可能已在控件或窗口中编写代码。 在这种情况下,您可以安全地调用,因为大多数情况下每个应用程序将有一个UI线程。

实际的静态调用是Dispatcher.CurrentDispatcher.BeginInvoke ,这不是你想要调用的东西(参见我对Hasan Khan的答案的评论)。

编辑:调用Application.Current.Dispatcher 并不是一件坏事。 (并且,为了清楚起见,它是一个实例属性,而不是静态 – 在Application的静态/单例实例上调用。)此属性将返回创建应用程序的线程的Dispatcher,并且通常是该线程UI也是在创建的 – 所以Application.Current.Dispatcher返回与myWindow.Dispatcher相同的Dispatcher。

静态调用Dispatcher.CurrentDispatcher (我警告过)会为你调用它的线程返回一个Dispatcher。 如果你从后台线程调用它,你将获得一个专门为该线程创建的新Dispatcher – 这通常不是你想要的。

首先,我认为重要的是要理解Dispatcher不是为处理大型后台操作而设计的。 它旨在将工作排入队列的UI线程。 这是一篇有关.NET线程模型和Dispatcher MSDN文章:

  • 线程模型,概述和调度程序

说实现Dispatcher.BeginInvoke方法的标准方法是在控件上调用它:

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

希望有所帮助!

虽然在大多数情况下使用DispatcherObject.Dispatcher (所有依赖项对象和控件inheritance自DispatcherObject等)或Application.Current.Dispatcher是正确的事情,因为通常只有一个UI线程,可以有多个UI线程和不同的窗口可以使用不同的调度程序。 在这种情况下,使用其调度程序更新控件很重要。 它存储在Dispatcher属性(inheritance自DispatcherObject ),此窗口中的任何其他控件和窗口本身。