我有一个带有树的UserControl。它使用多线程向其添加节点。我有一个名为Expand的函数,我需要在过滤完成后执行,因为我是多线程的新手,我不知道该怎么做。这是我的代码:
class MyClass : UserControl
{
private Thread nThread;
private bool searchLoadCompleted = false;
private void Filter()
{
ClearTree();
this.nThread = new Thread(new ParameterizedThreadStart(AddFilteredResultsToTree));
this.nThread.IsBackground = true;
this.nThread.Start(someParameter);
}
private void AddFilteredResultsToTree(int someParameter)
{
myTree.Invoke(new MethodInvoker( ()=> this.searchLoadCompleted = false ));
myTree.Invoke(new MethodInvoker( ()=> AppendNode(......) ));
myTree.Invoke(new MethodInvoker( ()=> this.searchLoadCompleted = true ));
}
private void Expand()
{
}
}
我尝试将nThread.Join()
添加到Expand()
中,但它无限期地被卡住了。我该怎么办?
答案 0 :(得分:2)
如果单线程版本是:
ClearTree();
AddFilteredResultsToTree(someparameter);
Expand();
不要打扰多线程,只需在同一个线程上执行即可。使用多线程的关键在于让主线程处理UI事件,如果你加入线程,那么你基本上只是在主线程中冻结(不做任何工作)时启动后台线程。请注意,通过调用Invoke,您实际上是将AddFilteredResultsToTree的执行委托给主线程。
我建议您只需从AddFilteredResult调用Expand,并根据需要使用Dispatcher更新UI。
另一种方法(我认为最好)是使用Async Pattern(示例和教程here),然后在AsyncCallback上更新UI。
答案 1 :(得分:1)
调用Invoke将阻止GUI线程和工作线程,因此没有工作线程的代码将不会有任何性能改进。