确保事情在WPF的UI线程上运行
我正在构build一个WPF应用程序。 我正在做一些与服务器端的asynchronous通信,我在客户端使用Prism的事件聚合。 这两件事情都会导致产生新的线程,而不是UI线程。 如果我试图在这些callback和事件处理程序线程上执行“WPF操作”,那么世界将会崩溃,现在它已经开始了。
首先,我遇到了问题,尝试在服务器的callback中创build一些WPF对象。 我被告知该线程需要在STA模式下运行。 现在我试图在Prism事件处理程序中更新一些UI数据,并告诉我:
调用者不能访问此线程,因为不同的线程拥有它。
所以; 什么是在WPF中正确使用的关键? 我已经阅读了这篇MSDN文章中的WPF Dispatcher。 我开始明白了,但我还不是巫师。
- 当我需要运行一些我不确定的东西时,总是使用Dispatcher.Invoke的关键是在UI线程上调用吗?
- 如果它实际上是在UI线程上调用,那么它是否重要?我仍然使用Dispatcher.Invoke?
- Dispatcher.Invoke =同步。 Dispathcher.BeginInvoke =asynchronous?
- 请问Dispatcher.Invoke请求UI线程,然后停下来等待呢? 这是不好的做法和风险较低的应对scheme?
- 我怎样才能得到调度员? 请问Dispatcher.CurrentDispatcher总是给我代表UI线程的调度程序?
- 会不会有一个以上的Dispatcher,或者是“Dispatcher”与应用程序的UI线程基本相同?
- 和BackgroundWorker有什么关系? 我什么时候用这个呢? 我认为这总是asynchronous?
- 一切运行在UI线程(通过被调用)运行在STA公寓模式? 也就是说,如果我有需要在STA模式下运行的东西 – Dispatcher.Invoke是否足够?
任何人想为我清理的东西? 任何相关的build议,等等? 谢谢!
逐个回答你的每一个问题:
- 不完全的; 你应该只在必要的时候调用UI线程。 见#2。
- 是的,这很重要。 你不应该自动
Invoke
一切。 关键是只在必要时调用到UI线程上。 为此,您可以使用Dispatcher.CheckAccess方法。 - 那是对的。
- 也是正确的,是的,你确实会面临风险较小的程序。 大多数情况下,您不会看到严重的性能下降(我们正在谈论上下文切换的毫秒数),但是您应该只在必要时进行
Invoke
。 这就是说,在某些方面是不可避免的,所以不,我不会说这是不好的做法。 这只是解决您偶尔遇到的一个问题。 - 在任何情况下,我已经看到,我已经与
Dispatcher.CurrentDispatcher
。 对于复杂的情况,这可能还不够,但我(个人)还没有看到它们。 - 不完全正确,但这种思路不会有任何伤害。 让我这样说:
Dispatcher
器可以用来访问应用程序的UI线程。 但它本身并不是UI线程。 - 当你有一个耗时的操作,并希望在后台运行该操作时维护响应式用户界面时,通常会使用
BackgroundWorker
。 通常,您不使用BackgroundWorker 而不是 Invoke,而是将BackgroundWorker 与 Invoke 结合使用 。 也就是说,如果您需要更新BackgroundWorker中的某个UI对象,则可以调用UI线程,执行更新,然后返回到原始操作。 - 是。 根据定义,WPF应用程序的UI线程必须在单线程单元中运行。
BackgroundWorker
有很多值得一提的地方,我相信很多问题已经被讨论过了,所以我不会深究。 如果您好奇,请查看BackgroundWorker类的MSDN页面 。