18

我想我需要一些帮助来理解Dispatcher Queue

当新工作到达时,它会被添加到调度程序队列的开头,而当调度程序想要处理一个工作项时,它会从开头删除。

更一般地说:如果有工作,它会以先进先出的方式存储在队列中,只要没有工作就处理。

此处的 MSDN 文档指的是 aloop和 a frame

The Dispatcher processes the work item queue in a loop. The loop is referred to as a frame.

但是在这种情况下,循环在哪里?对我来说,循环是对某些东西进行迭代的东西,当它到达终点时,它会重新开始。

a 的概念是frame什么?根据 MSDN 文档,一个框架是队列中工作项的一拳?如果这是真的,应该如何使用静态方法Disptatcher.PushFrame()

最有趣的问题是是否有任何方法可以获取队列的当前状态,尤其是队列中有多少项。

如果之前调用的方法(并因此放入 Dispatcher 队列)被执行,然后立即从队列中删除,或者它是否持续在另一个时间段内,它是否成立?

我知道,有很多问题:-)

4

1 回答 1

27

周围的文档很少Dispatcher,因此您必须拆解一下才能了解内部工作原理。

调度程序基本上是围绕应用程序的 消息泵执行工作的东西。有问题的那个位于windows 消息循环的顶部。

因此,只能有一个应用程序 Dispatcher - 可访问的全局 Dispatcher 对象Application.Current.Dispatcher。其他调度程序可以通过访问Dispatcher.CurrentDispatcher,根据文档

获取当前正在执行的线程的 Dispatcher,如果尚未与线程关联,则创建一个新的 Dispatcher。

但是,调用Run这个新的调度程序将被阻塞。

当您执行 aDispatcher.PushFrame时,它会将内部执行循环推入 Dispatcher - 这是frame的一般概念。DispatcherObject从诸如继承的任何东西DispatcherFrame都将其调度程序设置为当前调度程序。我们可以通过查看它的构造函数来验证这一点。

private Dispatcher _dispatcher;

protected DispatcherObject()
{
    this._dispatcher = Dispatcher.CurrentDispatcher;
}

当然,只有一个简单的事件循环是不够的——有时你需要颠覆当前的事件循环来强制完成其他工作。这就是为什么你有一个DispatcherFrame. 这实际上构成了事件循环。当您将帧推入 Dispatcher 时,会发生以下情况:

while (frame.Continue)
        {
            if (!this.GetMessage(ref msg, IntPtr.Zero, 0, 0))
            {
                break;
            }
            this.TranslateAndDispatchMessage(ref msg);
        }

TranslateAndDispatchMessage取出消息后,对 Dispatcher 中的优先队列进行评估。

如果一个操作在调度程序上运行需要很长时间,它会暂时停止事件循环,并且由于它不响应信号,应用程序似乎停止响应。

这是一篇文章,它使用框架通过允许事件循环快速运行来强制 UI 响应。

至于访问队列,照原样,在Dispatcher之外没有办法知道队列的状态。这是内部细节,不暴露在情理之中。

于 2012-07-10T18:40:13.917 回答