我想我需要一些帮助来了解Dispatcher Queue。
[当新工作到达时,它将被添加到调度程序队列的开头,而当分派器要处理工作项时,它将被从开头删除。
更笼统地说:如果有工作,它将以FIFO的方式存储在队列中,并在没有剩余工作的情况下进行处理。
MSDN文档here指的是loop
和frame
:
The Dispatcher processes the work item queue in a loop. The loop is referred to as a frame.
但是在这种情况下循环在哪里?对我来说,循环是对某事物的迭代,当它到达终点时,它又重新开始。
frame
的概念是什么?根据MSDN文档,框架是队列中工作项的重头戏吗?如果是这样,应该如何使用静态方法Disptatcher.PushFrame()
?
最有趣的问题是,是否有任何方法可以获取队列的当前状态,尤其是队列中有多少项目。
如果在执行之前已被调用的方法(并因此放入Dispatcher队列中,然后立即将其从队列中删除,或者该方法在内部持续另一个时间段,它是否成立?
我知道,这么多问题:-)
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响应。
就访问队列而言,实际上无法在分派器外部知道队列的状态。这是一个内部细节,因此没有公开是合理的。