【发布时间】:2011-01-06 22:46:46
【问题描述】:
我对调度程序有点困惑。假设我在后台线程上进行某种长时间的操作。我想更新我知道我通过调度程序执行此操作的 ui 线程。我的问题是,我是否像这样静态调用调度程序: Dispatcher.BeginInvoke(mywork) ... 或者在我要更新的控件上:mytextbox.Dispatcher.BeginInvoke(mywork)
【问题讨论】:
我对调度程序有点困惑。假设我在后台线程上进行某种长时间的操作。我想更新我知道我通过调度程序执行此操作的 ui 线程。我的问题是,我是否像这样静态调用调度程序: Dispatcher.BeginInvoke(mywork) ... 或者在我要更新的控件上:mytextbox.Dispatcher.BeginInvoke(mywork)
【问题讨论】:
值得注意的是,调用Dispatcher.BeginInvoke不是静态调用:它是一个隐含的this.Dispatcher.BeginInvoke。如果您可以使用此调用,那么您很可能已经在控件或窗口中编写代码。在这种情况下,您可能可以安全地调用其中任何一个,因为大多数情况下每个应用程序都有一个 UI 线程。
实际的静态调用将是 Dispatcher.CurrentDispatcher.BeginInvoke,这不是您想要调用的东西(请参阅我对 Hasan Khan 的回答的评论了解原因)。
编辑:调用Application.Current.Dispatcher 不是一件坏事。 (并且,为了清楚起见,它是一个实例属性,而不是静态 - 在 Application 的静态/单例实例上调用。)此属性将返回创建应用程序的线程的调度程序,通常是线程UI 也是在上面创建的 - 所以Application.Current.Dispatcher 返回的调度程序与myWindow.Dispatcher 相同。
静态调用Dispatcher.CurrentDispatcher(我警告过)为您调用它的线程返回一个调度程序。如果您从后台线程调用它,您将获得一个专门为该线程创建的新 Dispatcher - 这通常不是我们想要的。
【讨论】:
Application.Current.Dispatcher是个坏主意?到目前为止,我在我的应用程序中使用它没有任何问题。它只需要调用Application().Run()。
Application.Current.Dispatcher 没有任何问题(而且我没有说有)。 Application.Current.Dispatcher 和 Dispatcher.CurrentDispatcher 的行为非常不同!
首先我认为了解Dispatcher 不是为处理大型后台操作而设计的很重要。它旨在对对象的 UI 线程上的工作进行排队。这是一篇关于 .NET 线程模型和Dispatcher 的有价值的 MSDN 文章:
说实现Dispatcher.BeginInvoke 方法的标准方式是在控件上调用它:
startStopButton.Dispatcher.BeginInvoke(
DispatcherPriority.Normal, new NextPrimeDelegate(CheckNextNumber)
);
希望有帮助!
【讨论】:
虽然在大多数情况下使用DispatcherObject.Dispatcher(所有依赖对象和控件都继承自DispatcherObject等)或Application.Current.Dispatcher是正确的做法,因为通常只有一个UI线程,可以有多个UI线程,不同的窗口可以使用不同的调度器。在这种情况下,使用其调度程序更新控件很重要。它存储在其Dispatcher 属性(继承自DispatcherObject)、此窗口中的任何其他控件以及窗口本身中。
【讨论】: