应用程序调度程序和控制调度程序

时间:2011-11-26 16:58:20

标签: wpf controls dispatcher

假设我有名为“button1”的控制按钮和名为“doSomething”的功能。函数“doSomething”从另一个线程调用。

我有两种方法从UI线程调用函数doSomething。

首先,从控制按钮调度程序

this.button1.Dispatcher.BeginInvoke(new Action(() => { doSomething(); }));

,其次,来自应用程序调度程序

this.Dispatcher.BeginInvoke(new Action(() => { doSomething(); }));

结果是一样的,真​​正不同的是什么?

3 个答案:

答案 0 :(得分:4)

在同一个线程拥有的所有控件中引用相同的调度程序实例。没有区别。

答案 1 :(得分:3)

所有UI控件(正常创建)共享同一个调度程序实例。该调度程序正在处理UI线程。如果你在backgroud线程上创建一些控件,它将在该线程上创建新的调度程序,这将不是很好。 避免WinForms和WPF中的线程和UI控件的大多数问题的最佳方法是使用System.Threading.SynchronizationContext.Current。工作流程很简单:当您使用UI线程时获得System.Threading.SynchronizationContext.Current并将其保存在某处(例如,在公共静态字段中)。然后,只要您想在UI线程上运行某些代码,就可以访问该持久性SynchronizationContext intance并使用其SendPost方法。它将在线程上运行代理,其中SynchronizationContext已实现(对于UI线程的当前情况)。另外它足够聪明,使用当前的Invoking方式(WinForms的消息循环和WPF的调度程序),如果你已经从UI线程调用它将只是同步运行你的委托。 请记住,只有在当前UI线程上创建第一个控件后才能获得SynchronizationContext,因为SynchronizationContext将在此之后立即初始化。

答案 2 :(得分:0)

在大多数情况下,我们有单个UI线程。所以,你打电话

并没有什么不同
control.Dispatcher(which comes inherited from DispatcherObject parent of the controls).

or 

Disptacher.Current.

但是有些情况下,你最终会有多个调度员。 因此,在那种情况下,Control.Dispatcher将提供帮助,因为它将找出当前的调度程序以尊重线程亲和力。在这个Dispatcher.Current赢得了帮助。

一种情况是,具有用于显示忙指示符的专用线程(带有调度程序)作为默认UI线程正忙于呈现大型控件列表。

但是,使用SynchronizationContext是另一种避免此类问题的方法。但是,如果不再需要该上下文或线程,或者任何其他开发人员将其设置为null,该怎么办?所以,在我看来,最好选择Control.Dispatcher。