我想我需要一些帮助来理解调度程序队列。
当新工作到达时,它将被添加到dispatcher队列的开头,当Dispatcher想要处理一个工作项时,它会从开始时被删除。
更一般的说法是:如果有工作,它就会以FIFO方式存储在队列中,并且只要没有剩余的工作就会被处理。
MSDN文档这里指的是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队列)被执行,然后立即从队列中删除它,或者它是否在内部持续了一段时间,那么它是否有效?
我知道,有很多问题:-)
发布于 2012-07-10 18:40:13
有关Dispatcher的文档非常少,因此您必须稍微分解一下才能了解内部的工作原理。
调度程序基本上是围绕应用程序的讯息泵执行工作的东西。有问题的人坐在windows消息循环的顶端。
因此,只能有一个应用程序调度程序-- Application.Current.Dispatcher可以访问的全局Dispatcher对象。其他调度程序可以通过访问Dispatcher.CurrentDispatcher来实现,而根据文档,这是可能的
获取当前正在执行的线程的Dispatcher,如果一个线程尚未与线程关联,则创建一个新的Dispatcher。
但是,在这个新的调度程序上调用Run将被阻塞。
当您执行Dispatcher.PushFrame时,它会将内部执行循环推入Dispatcher --这是框架的一般概念。从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中,在获取消息之后,调度程序中的优先级队列才会得到评估。
如果一个操作在dispatcher上运行需要很长时间,它会暂时停止事件循环,并且由于它不响应信令,所以应用程序似乎停止了响应。
这是一篇文章使用框架强制UI响应,允许事件循环在短时间内运行。
至于访问队列,就像它一样,无法知道调度程序之外队列的状态。这是一个内部细节,没有暴露是合理的。
https://stackoverflow.com/questions/11417216
复制相似问题