在项目中也是经常用到:
刚见到它时,你会想:为什么不直接使用System.Windows命名空间下的MessageBox类,何必要这么麻烦?(认真分析看它做了什么,具体原因下面解释)
主要介绍的方法:
- Dispatcher.Invoke 方法
作用:在与 Dispatcher 关联的线程上同步执行指定的委托。
- Dispatcher.CheckAccess 方法
作用:确定调用线程是否为与此 Dispatcher 关联的线程。
注:CheckAccess 可以从任意线程中调用。CheckAccess 和 VerifyAccess 之间的区别在于 CheckAccess 将返回一个布尔值,指示调用线程是否可以访问 Dispatcher,而VerifyAccess 将引发一个异常。
PS:在 WPF 中,只有创建 DispatcherObject 的线程才能访问该对象。 例如,一个从主 UI 线程派生的后台线程不能更新在该 UI 线程上创建的 Button的内容。 为了使该后台线程能够访问 Button 的 Content 属性,该后台线程必须将此工作委托给与该 UI 线程关联的 Dispatcher。 使用 Invoke 或BeginInvoke 来完成此操作。 Invoke 是同步操作,而 BeginInvoke 是异步操作。 该操作将按指的 DispatcherPriority 添加到 Dispatcher 的事件队列中。
Invoke 是同步操作;因此,直到回调返回之后才会将控制权返回给调用对象。
BeginInvoke 是异步操作;因此,调用之后控制权会立即返回给调用对象。
BeginInvoke 返回一个 DispatcherOperation 对象,当委托位于事件队列中时,该对象可用于与委托进行交互。
由 BeginInvoke 返回的 DispatcherOperation 对象可以采用多种方式与指定的委托进行交互,例如:
-
当在事件队列中挂起执行时,更改委托的 DispatcherPriority。
-
从事件队列中移除委托。
-
等待委托返回。
-
获取委托执行之后返回的值。
如果按同一个 DispatcherPriority 调用多个 BeginInvoke,将按调用发生的顺序执行它们。
如果对某个已关闭的 Dispatcher 调用 BeginInvoke,则返回的 DispatcherOperation 的状态属性将设置为 Aborted。
MSDN示例e:
使用 CheckAccess 确定某个线程是否可以访问 Button。通过调用与 Button 关联的 Dispatcher 上的 CheckAccess 方法可以验证是否可以访问该线程。 如果调用线程可以访问 Dispatcher,则可通过访问 Button 的成员来更新 Button;否则,将接受 Button 作为参数的委托放置到Dispatcher 中。 Dispatcher 将委托更新 Button 的工作。
// Uses the Dispatcher.CheckAccess method to determine if // the calling thread has access to the thread the UI object is on. private void TryToUpdateButtonCheckAccess(object uiObject) { Button theButton = uiObject as Button; if (theButton != null) { // Checking if this thread has access to the object. if (theButton.Dispatcher.CheckAccess()) { // This thread has access so it can update the UI thread. UpdateButtonUI(theButton); } else { // This thread does not have access to the UI thread. // Place the update method on the Dispatcher of the UI thread. theButton.Dispatcher.BeginInvoke(DispatcherPriority.Normal, new UpdateUIDelegate(UpdateButtonUI), theButton); } } }