确保事情在WPF的UI线程上运行

我正在构build一个WPF应用程序。 我正在做一些与服务器端的asynchronous通信,我在客户端使用Prism的事件聚合。 这两件事情都会导致产生新的线程,而不是UI线程。 如果我试图在这些callback和事件处理程序线程上执行“WPF操作”,那么世界将会崩溃,现在它已经开始了。

首先,我遇到了问题,尝试在服务器的callback中创build一些WPF对象。 我被告知该线程需要在STA模式下运行。 现在我试图在Prism事件处理程序中更新一些UI数据,并告诉我:

调用者不能访问此线程,因为不同的线程拥有它。

所以; 什么是在WPF中正确使用的关键? 我已经阅读了这篇MSDN文章中的WPF Dispatcher。 我开始明白了,但我还不是巫师。

  1. 当我需要运行一些我不确定的东西时,总是使用Dispatcher.Invoke的关键是在UI线程上调用吗?
  2. 如果它实际上是在UI线程上调用,那么它是否重要?我仍然使用Dispatcher.Invoke?
  3. Dispatcher.Invoke =同步。 Dispathcher.BeginInvoke =asynchronous?
  4. 请问Dispatcher.Invoke请求UI线程,然后停下来等待呢? 这是不好的做法和风险较低的应对scheme?
  5. 我怎样才能得到调度员? 请问Dispatcher.CurrentDispatcher总是给我代表UI线程的调度程序?
  6. 会不会有一个以上的Dispatcher,或者是“Dispatcher”与应用程序的UI线程基本相同?
  7. 和BackgroundWorker有什么关系? 我什么时候用这个呢? 我认为这总是asynchronous?
  8. 一切运行在UI线程(通过被调用)运行在STA公寓模式? 也就是说,如果我有需要在STA模式下运行的东西 – Dispatcher.Invoke是否足够?

任何人想为我清理的东西? 任何相关的build议,等等? 谢谢!

逐个回答你的每一个问题:

  1. 不完全的; 你应该只在必要的时候调用UI线程。 见#2。
  2. 是的,这很重要。 你不应该自动Invoke一切。 关键是只在必要时调用到UI线程上。 为此,您可以使用Dispatcher.CheckAccess方法。
  3. 那是对的。
  4. 也是正确的,是的,你确实会面临风险较小的程序。 大多数情况下,您不会看到严重的性能下降(我们正在谈论上下文切换的毫秒数),但是您应该只在必要时进行Invoke 。 这就是说,在某些方面是不可避免的,所以不,我不会说这是不好的做法。 这只是解决您偶尔遇到的一个问题。
  5. 在任何情况下,我已经看到,我已经与Dispatcher.CurrentDispatcher 。 对于复杂的情况,这可能还不够,但我(个人)还没有看到它们。
  6. 不完全正确,但这种思路不会有任何伤害。 让我这样说: Dispatcher 器可以用来访问应用程序的UI线程。 但它本身并不是UI线程。
  7. 当你有一个耗时的操作,并希望在后台运行该操作时维护响应式用户界面时,通常会使用BackgroundWorker 。 通常,您不使用BackgroundWorker 而不是 Invoke,而是将BackgroundWorker Invoke 结合使用 。 也就是说,如果您需要更新BackgroundWorker中的某个UI对象,则可以调用UI线程,执行更新,然后返回到原始操作。
  8. 是。 根据定义,WPF应用程序的UI线程必须在单线程单元中运行。

BackgroundWorker有很多值得一提的地方,我相信很多问题已经被讨论过了,所以我不会深究。 如果您好奇,请查看BackgroundWorker类的MSDN页面 。