Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Wpf 应用程序调度器和控制调度器_Wpf_Controls_Dispatcher - Fatal编程技术网

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

Wpf 应用程序调度器和控制调度器,wpf,controls,dispatcher,Wpf,Controls,Dispatcher,假设我有名为“button1”的控制按钮和名为“doSomething”的函数。函数“doSomething”是从另一个线程调用的 我有两种方法从UI线程调用函数doSomething 首先,从控制按钮调度器 this.button1.Dispatcher.BeginInvoke(new Action(() => { doSomething(); })); this.Dispatcher.BeginInvoke(new Action(() => { doSomething(); }

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

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

首先,从控制按钮调度器

this.button1.Dispatcher.BeginInvoke(new Action(() => { doSomething(); }));
this.Dispatcher.BeginInvoke(new Action(() => { doSomething(); }));
第二,来自应用程序调度器

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

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

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

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

在大多数情况下,我们只有一个UI线程。所以,你打电话也没关系

control.Dispatcher(which comes inherited from DispatcherObject parent of the controls).

or 

Disptacher.Current.
但在某些情况下,最终会有多个调度器。 因此,在这种情况下,Control.Dispatcher将提供帮助,因为它将找到当前的调度器以尊重线程关联性。在此调度程序中。当前将不起作用

一种情况是,使用专用线程(带有dispatcher)将忙碌指示器显示为默认UI线程,而该线程正忙于呈现大型控件列表


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

你的意思是Dispatcher是静态的,由一个线程(UI线程)拥有?@brian:静态字段是静态的,从这个意义上讲,它不是静态的,每个线程只有一个实例。应用程序引用UI-tread的调度程序。该函数是从其父级(窗口或控件)继承的,由UI线程拥有,对吗?@brian:它不是继承的,它来自基类型的构造函数,什么:“在构造时,DispatcherObject存储对链接到当前运行线程的Dispatcher的引用。“单例调度器呢?我认为dispatcher比SynchronizationContext简单得多。当然,您可以将dispatcher另存为singleton。只是SynchronizationContext在用法上几乎相同,而且您的代码对于WinForms、Wpf以及可能未来的框架都是统一的。简单地使用Application.Current.Dispatcher.Invoke(…)来调用UI线程上的方法不是很好吗?