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
),此窗口中的任何其他控件和窗口本身。