了解Dispatcher队列

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

当新工作到达时,它会在调度程序队列的开头添加,并且当Dispatcher想要处理工作项时,它将从头开始删除。

更一般地说:如果有工作,它将以FIFO的方式存储在队列中,并且只要没有工作就可以处理。

这里的MSDN文档指的是loopframe

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

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

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

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

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

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

Dispatcher周围的文档非常少,因此您需要对其进行反汇编以了解内部工作原理。

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

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

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

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

当您执行Dispatcher.PushFrame ,它基本上将帧推送到当前调度程序。 从DispatcherObjectinheritance的任何内容(如DispatcherFrame都会将其调度程序设置为当前的调度程序。 我们可以通过查看它的构造函数来validation这一点。

 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之外的队列状态。 这是一个内部细节,它没有暴露是合理的。