c#:在控件调用列表中进入代理队列

问题描述

| 假设我将采用树视图并以BFS方式并以线程安全的方式添加一些节点。
treeView.Invoke((MethodInvoker)delegate{treeView.Nodes.Add(someNode);});
后来我想向添加到treeView的节点之一添加一个节点(随着我的深度增加一)。我怎么知道treeView在添加第二层节点之前已经添加一个节点的所有深度。顺便说一下,第二级的信息取决于第一级。所有这些只是我所需要的一个例子,但这是眼下真正的问题的第二要件。 也许有人扩展了一个节点,我想先向该节点添加节点...在这种情况下,我想中断treeView的调用列表,并开始在扩展的节点处添加节点。 我该怎么做这些任务? 我想我可以以深度优先的方式添加节点,但是我不想这样做。有没有更好的办法? 我真的很讨厌消息/代理队列正在幕后形成的想法,我对此无能为力。     

解决方法

代表如何在后台排队 实际的委托存储在已创建其句柄的控件或最接近的父控件上的名为threadCallbackList的私有字段中的队列中。数据结构仅为
System.Collections.Queue
。 知道TreeView已添加了所有的深度一节点 如果要与主线程通信,即节点已填充了所有子节点,则可以在节点的
Tag
属性中存储一些内容(一个枚举)以表明这一点。 如果您认为需要与后台线程通信,则将最后一个节点添加到树视图级别的委托已在后台线程运行,您不必这样做。您使用
BeginInvoke
Invoke
提交的代表将按顺序执行。 中断
BeginInvoke
d​​代表的执行 您无法通过单击同一线程上的控件来中断UI线程上排队的委托的执行。委托执行与程序的任何其他部分一样。这是一个使每个委托出队并执行它们的循环。您的UI线程将执行这些委托,因此它也无法执行将试图中断排队委托的执行的click事件处理程序。即使您能弄清楚如何使用反射来使排队的委托人混乱,也无法在其他代码在同一线程中运行的同时进行反射。 可能的解决方案 听起来您只是担心会淹没UI线程。如果是这种情况,您可以通过每N个调用
Invoke
而不是
BeginInvoke
来限制后台线程。这将导致您的后台工作线程等待,直到刷新队列为止(至少直到该调用中传递的委托为止)。这样,您一次最多不会有N个排队的代表。如果您沿着那条路线走,每次可以could4ѭ,然后用
AddRange(someNodes)
代替
Add(someNode)
。