C# WPF/线程:控件上的调度程序静态与调度程序?

C# WPF/线程:控件上的调度程序静态与调度程序?,c#,wpf,C#,Wpf,我对调度员有点困惑。假设我在后台线程上执行某种长操作。我想更新ui线程,我知道我是通过dispatcher完成的。我的问题是,我是否静态地调用调度器,比如:dispatcher.BeginInvoke(mywork)。。。或者在我要更新的控件上:mytextbox.Dispatcher.BeginInvoke(mywork)首先,我认为重要的是要理解,该控件不是为处理大型后台操作而设计的。它被设计为在对象的UI线程上对工作进行排队。下面是一篇有价值的MSDN文章,介绍.NET线程模型和:

我对调度员有点困惑。假设我在后台线程上执行某种长操作。我想更新ui线程,我知道我是通过dispatcher完成的。我的问题是,我是否静态地调用调度器,比如:dispatcher.BeginInvoke(mywork)。。。或者在我要更新的控件上:mytextbox.Dispatcher.BeginInvoke(mywork)

首先,我认为重要的是要理解,该控件不是为处理大型后台操作而设计的。它被设计为在对象的UI线程上对工作进行排队。下面是一篇有价值的MSDN文章,介绍.NET线程模型和:

表示实现该方法的标准方法是在控件上调用它:

startStopButton.Dispatcher.BeginInvoke(
    DispatcherPriority.Normal, new NextPrimeDelegate(CheckNextNumber)
);

希望有帮助

值得注意的是,调用
Dispatcher.BeginInvoke
不是静态调用:它是隐式的
this.Dispatcher.BeginInvoke
。如果可以使用此调用,则可能已经在控件或窗口中编写了代码。在这种情况下,您可以安全地调用这两个应用程序,因为大多数情况下每个应用程序都有一个UI线程

实际的静态调用是
Dispatcher.CurrentDispatcher.BeginInvoke
,这不是您想要调用的(请参阅我对Hasan Khan答案的评论,了解原因)

编辑:调用
应用程序.Current.Dispatcher
并不是一件坏事。(而且,为了清楚起见,它是一个实例属性,而不是静态的-在
应用程序的静态/单一实例上调用)此属性将返回创建应用程序时使用的线程的调度程序,通常,这也是创建UI的线程-因此
Application.Current.Dispatcher
返回与
myWindow.Dispatcher
相同的Dispatcher


静态调用
Dispatcher.CurrentDispatcher
(我警告过)为调用它的线程返回一个Dispatcher。如果您从后台线程调用它,您将得到一个专门为该线程创建的新调度程序-这通常不是您想要的。

而在大多数情况下,使用
DispatcherObject.Dispatcher
(所有依赖项对象和控件都继承自
DispatcherObject
)或者
Application.Current.Dispatcher
是正确的做法,因为通常只有一个UI线程,可以有多个UI线程,不同的窗口可以使用不同的Dispatcher。在这种情况下,使用调度程序更新控件非常重要。它存储在其
Dispatcher
属性(继承自
DispatcherObject
)中,以及此窗口和窗口本身中的任何其他控件中。

为什么使用
Application.Current.Dispatcher
是个坏主意?我在应用程序中使用它,到目前为止没有任何问题。它所需要的只是调用
Application().Run()
。@Aphex:我的回答是编辑,因为我无法将它放入注释中-但是
Application.Current.Dispatcher
(我没有说过有)
Application.Current.Dispatcher
Dispatcher.CurrentDispatcher
的行为非常不同!有些情况下,使用Application.Current.Dispatcher是不安全的(尽管非常罕见),例如,在WinForms(或任何其他非WPF)应用程序(Application.Current为null)中托管WPF控件,或者在同一应用程序中有多个UI线程(共享应用程序资源有很多问题,但该情况仍然相关)。因此,最安全的方法是使用control.Dispatcher