了解调度程序队列

问题描述 投票:17回答:1

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

[当新工作到达时,它将被添加到调度程序队列的开头,而当分派器要处理工作项时,它将被从开头删除。

更笼统地说:如果有工作,它将以FIFO的方式存储在队列中,并在没有剩余工作的情况下进行处理。

MSDN文档here指的是loopframe

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

但是在这种情况下循环在哪里?对我来说,循环是对某事物的迭代,当它到达终点时,它又重新开始。

frame的概念是什么?根据MSDN文档,框架是队列中工作项的重头戏吗?如果是这样,应该如何使用静态方法Disptatcher.PushFrame()

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

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

我知道,这么多问题:-)

c# wpf asynchronous dispatcher method-invocation
1个回答
26
投票

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

调度程序基本上就是围绕应用程序的Message Pump执行工作的东西。有问题的一个位于windows message loop的顶部。

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

为当前正在执行的线程获取分派器,并创建一个新的Dispatcher(如果尚未与该线程关联)。

但是,在此新调度程序上调用Run将被阻止。

[当您执行Dispatcher.PushFrame时,它将内部执行循环推入分派器-这是frame的基本概念。从DispatcherObject继承的任何内容,例如DispatcherFrame,都将其派遣程序设置为当前派遣程序。我们可以通过查看其构造函数来验证这一点。

private Dispatcher _dispatcher;

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

当然,仅具有简单的事件循环是不够的-有时您需要颠覆当前事件循环以强制执行其他工作。这就是为什么您有一个DispatcherFrame。这实际上是事件循环的组成部分。当您将框架推入分派器时,会发生以下情况:

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

[取出消息后,在TranslateAndDispatchMessage中对分派器中的优先队列进行评估。

如果操作需要很长时间才能在调度程序上运行,它将暂时停止事件循环,并且由于它不响应信令,因此应用程序似乎停止了响应。

[Here's an article,它使用框架通过允许事件循环立即运行来强制UI响应。

就访问队列而言,实际上无法在分派器外部知道队列的状态。这是一个内部细节,因此没有公开是合理的。

© www.soinside.com 2019 - 2024. All rights reserved.