C# Note28: Dispatcher类

  • Post author:
  • Post category:其他


在项目中也是经常用到:

刚见到它时,你会想:为什么不直接使用

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);
        }
    }
}

转载于:https://www.cnblogs.com/carsonzhu/p/7451475.html