【发布时间】:2014-07-27 11:41:58
【问题描述】:
我对线程很陌生,所以我的想法和问题可能有点傻:)
我用来自另一个线程的数据填充WinForm 控件,所以当我尝试访问控件时我必须调用Invoke()。
如果我理解正确的话,treeView.BeginInvoke(/*some Action()*/) 会让这个Action<>() 在主线程中运行。但是我“解雇并忘记”这个BeginInvoke(),所以我不知道工作何时真正完成。而且即使工作线程关闭并且执行返回到主线程,我也不能确定所有BeginInvoke() 方法都已完成执行。
这就是为什么即使在返回主线程后我也无法使用 Control 进行管理,我将 BeginInvoke() 解雇。
实际问题是TreeView.ExpandAll()不起作用。
看看下面的代码sn-p。
private void btnGetTree_Click(object sender, EventArgs e) {
var treeViewWriter = new Thread(() => UpdateTreeView(new AddXmlNodeArgs(di, null), treeDirectoryContents));
treeViewWriter.Start();
treeViewWriter.Join();
treeDirectoryContents.ExpandAll();
}
// method runs on a worker thread
public static void UpdateTreeView(AddXmlNodeArgs args, TreeView treeView) {
// I will miss details... Here is the code that I run for every new TreeNode:
treeView.UpdateTree((TreeView tree) => {
tree.Nodes[0].Nodes.Add(newTreeNode); // treeView.Nodes[0]...
});
}
// Extension method for TreeView
public static void UpdateTree(this TreeView tree, Action<TreeView> code) {
if (tree.InvokeRequired)
tree.BeginInvoke(code, tree);
else
code.Invoke(tree);
}
我解雇了tree.BeginInvoke(),但我不会在任何地方打电话给EndInvoke()。所以我猜当btnGetTree_Click 执行达到treeDirectoryContents.ExpandAll() 时——并非所有Invoke() 方法都完成了它们的工作。这就是为什么.ExpandAll() doesn't work。
如果我错了,请纠正我,并请给出如何解决此问题的建议。
【问题讨论】:
-
为什么要创建一个线程,然后在
btnGetTree_Click中等待它完成?这种用法不需要线程 -
@L.B 我只发布了您需要查看以了解我的问题的代码。我在
btnGetTree_Click中有多个线程,它们的工作方式类似于“生产者/多个消费者” -
这一切最初都是从这里开始的:stackoverflow.com/questions/24975972/…
-
@jamesbong 似乎是学习 TPL 库和 async/await 的好时机。启动多个Tasks 然后
await Task.WhenAll(...)
标签: c# .net multithreading winforms treeview