mar*_*man 17 c# wpf asynchronous dispatcher method-invocation
我想我需要一些帮助来理解Dispatcher Queue.
当新工作到达时,它会在调度程序队列的开头添加,并且当Dispatcher想要处理工作项时,它将从头开始删除.
更一般地说:如果有工作,它将以FIFO方式存储在队列中并且只要没有工作就可以处理.
这里的MSDN文档是指a loop
和a frame
:
The Dispatcher processes the work item queue in a loop. The loop is referred to as a frame.
但在这种情况下,循环在哪里?对我来说,循环是迭代某些东西的东西,当它到达终点时,它会重新开始.
什么是概念frame
?根据MSDN文档,框架是队列中工作项的一击?如果这是真的,应该如何使用静态方法Disptatcher.PushFrame()
?
最有趣的问题是,是否有任何方法可以获得队列的当前状态,尤其是队列中有多少项.
如果之前调用的方法(以及因此放入Dispatcher队列中)被执行,然后立即将其从队列中删除或者在内部持续另一段时间,它是否成立?
我知道,这么多问题:-)
Ast*_*sti 26
围绕着它的文档非常少Dispatcher
,所以你必须对它进行反汇编以了解内部工作原理.
调度程序基本上是围绕应用程序的消息泵执行工作的东西 .有问题的一个位于Windows消息循环的顶部.
因此,只能有一个应用程序Dispatcher - 可访问的全局调度程序对象Application.Current.Dispatcher
.其他调度员可以通过访问Dispatcher.CurrentDispatcher
,根据文档
获取当前正在执行的线程的Dispatcher,并创建一个新的Dispatcher(如果尚未与该线程关联).
但是,调用Run
这个新的调度程序将会阻塞.
当你这样做时Dispatcher.PushFrame
,它基本上将一个帧推到当前的调度程序上.任何继承自DispatcherObject
此类的东西DispatcherFrame
都会将其调度程序设置为当前的调度程序.我们可以通过查看它的构造函数来验证这一点.
private Dispatcher _dispatcher;
protected DispatcherObject()
{
this._dispatcher = Dispatcher.CurrentDispatcher;
}
Run Code Online (Sandbox Code Playgroud)
当然,拥有一个简单的事件循环是不够的 - 有时您需要破坏当前的事件循环以强制完成其他工作.这就是为什么你有一个DispatcherFrame
.这实际上构成了事件循环.当您将帧推入Dispatcher时,会发生以下情况:
while (frame.Continue)
{
if (!this.GetMessage(ref msg, IntPtr.Zero, 0, 0))
{
break;
}
this.TranslateAndDispatchMessage(ref msg);
}
Run Code Online (Sandbox Code Playgroud)
在TranslateAndDispatchMessage
取消消息之后,Dispatcher中的优先级队列被评估.
如果一个操作需要很长时间才能在调度程序上运行,它会暂时停止事件循环,并且因为它不响应信号,应用程序似乎停止响应.
这篇文章使用框架强制UI响应,允许事件循环很快运行.
至于访问队列,实际上,无法知道Dispatcher外部队列的状态.这是一个内部细节,它没有暴露是合理的.
归档时间: |
|
查看次数: |
17711 次 |
最近记录: |