我在调度程序方面有点困惑。比如我在一个后台线程中执行某个长时间操作,我想要更新ui线程,我知道可以通过调度程序来实现。我的问题是,我应该静态地调用调度程序吗,比如 Dispatcher.BeginInvoke(mywork) ... 还是在我想要更新的控件上调用:mytextbox.Dispatcher.BeginInvoke(mywork)
Dispatcher.BeginInvoke
不是静态调用:它是一个隐式的this.Dispatcher.BeginInvoke
。如果你可以使用这个调用,你很可能已经在控件或窗口中编写了代码。在这种情况下,通常情况下每个应用程序都有一个UI线程,所以你可能可以安全地调用任何一个。Dispatcher.CurrentDispatcher.BeginInvoke
,这并不是你想要调用的(请参见我的评论Hasan Khan的答案为什么)。
编辑:调用Application.Current.Dispatcher
并不是一件坏事。(为了明确起见,它是一个实例属性,而不是静态的——在一个静态/单例实例上被调用)。该属性将返回创建应用程序的线程的Dispatcher,通常情况下也是创建UI的线程——因此Application.Current.Dispatcher
返回与myWindow.Dispatcher
相同的Dispatcher。Dispatcher.CurrentDispatcher
(我警告过的)会返回从其调用的线程的Dispatcher。如果你从后台线程调用它,你会得到一个专门为该线程创建的新的Dispatcher——这通常不是想要的。首先,我认为理解Dispatcher
的重要性在于它不是设计用来处理大型后台操作的。它被设计用来在对象的UI线程上排队工作。这里有一篇值得阅读的MSDN文章,介绍了.NET线程模型和Dispatcher
:
可以说实现Dispatcher.BeginInvoke
方法的标准方式是在控件上调用它:
startStopButton.Dispatcher.BeginInvoke(
DispatcherPriority.Normal, new NextPrimeDelegate(CheckNextNumber)
);
虽然在大多数情况下,使用DispatcherObject.Dispatcher
(所有依赖对象和控件都继承自DispatcherObject
等)或Application.Current.Dispatcher
是正确的做法,因为通常只有一个UI线程,但可能会存在多个UI线程,不同的窗口可以使用不同的调度程序。在这种情况下,重要的是使用其调度程序更新控件。它存储在其Dispatcher
属性中(从DispatcherObject
继承),此窗口中的任何其他控件和窗口本身。
Application.Current.Dispatcher
是一个不好的主意?我在我的应用程序中使用它,到目前为止没有任何问题。它只需要调用Application().Run()
。 - AphexApplication.Current.Dispatcher
没有任何问题(我也没有说过有问题)。Application.Current.Dispatcher
和Dispatcher.CurrentDispatcher
的行为非常不同! - Dan Puzey