c#:获取控件调用列表中的委托队列
本文关键字:队列 列表 获取 控件 调用 | 更新日期: 2023-09-27 17:57:47
假设我要以BFS的方式,但也要以线程安全的方式,获取树视图并添加一些节点。
treeView.Invoke((MethodInvoker)delegate{treeView.Nodes.Add(someNode);});
稍后,我想将一个节点添加到添加到treeView的一个节点中(随着深度的增加)。我怎么知道treeView在添加第二层节点之前已经添加了它的所有深度一节点。顺便说一下,第二级的信息取决于第一级。所有这些只是我所需要的一个例子,但它是次要的,而不是手头的真正问题。
也许有人扩展了一个节点,我想先将节点添加到该节点。。。在这种情况下,我想中断treeView的调用列表,并开始在扩展的节点上添加节点。
我怎样才能完成这两项任务?
我想我可以以深度优先的方式添加节点,但我不想。有更好的方法吗?
我真的很讨厌消息/委托队列在引擎盖下形成而我无法控制它的想法。
代表如何在引擎盖下排队
实际委托存储在一个名为threadCallbackList的专用字段中的队列中,该字段位于控件或其句柄已创建的最近父控件上。数据结构只是一个System.Collections.Queue
。
知道TreeView已经添加了它的所有深度一个节点
如果您想向主线程传达一个节点已经填充了它的所有子级,您可以在节点的Tag
属性中存储一些东西(枚举)来指示这一点。
如果您认为需要向后台线程传达将最后一个节点添加到树视图级别的委托已经运行的信息,则不需要。您使用BeginInvoke
和Invoke
提交的委托将按顺序执行。
中断BeginInvoke
d委托的执行
您无法通过单击同一线程上的控件来中断UI线程上排队委托的执行。委托执行与程序的任何其他部分一样。这是一个循环,它将每个委托排成队列并执行它们。您的UI线程将执行这些委托,因此它不能同时执行试图中断排队委托执行的单击事件处理程序。即使你能想出如何使用反射来处理排队的委托,你也不可能在其他代码在同一线程中运行的同时执行
可能的解决方案
听起来你只是担心淹没你的UI线程。如果是这种情况,您可以通过每N次调用Invoke
而不是BeginInvoke
来限制后台线程。这将导致后台工作线程等待队列被刷新(至少到该调用中传递的委托为止)。这样一来,一次排队的代表就永远不会超过N个。如果你走那条路,你可以每次只使用Invoke
,并使用AddRange(someNodes)
而不是Add(someNode)
。