2016-03-21 37 views
2

我有一个多线程应用程序,我需要从另一个线程添加对象到树视图。但我不断收到异常如何从另一个线程在treeview中添加对象

正在对此控件执行的操作是由错误的线程调用的。使用Control.Invoke或Control.BeginInvoke对正确的线程进行编组来执行此操作。

这里是我的代码

ThreadPool.QueueUserWorkItem(new WaitCallback(GetFiles), entryPoint); 

private void GetFiles(object entryPoint) 
{ 
     var localData = entryPoint as EntryPoint; 
     this.GetFiles(localData.DirectoryInfo, localData.TreeNode); 
     localData.ManualEvent.Set(); 
} 

private void GetFiles(DirectoryInfo directory, TreeNode tree) 
{ 
    for (int i = 0; i < allFiles.GetLength(0); i++) 
    { 
     tree.Nodes.Add(allFiles[i].Name); 
    } 
} 
+1

这是一个标准消息,您不能修改由非UI线程的UI线程创建的元素。将BeginInvoke()与您的线程的mainform中的匿名委托或常​​用委托一起使用。我认为,lambda和linq甚至提供更好的方法。 – icbytes

+0

我在委托的帮助下做的,但仍然收到一个异常public delegate void MyDelagate(TreeNode tree,string value); public MyDelagate TreeViewDelegate; TreeViewDelegate =委托(TreeNode树,字符串s) { tree.Nodes.Add(s); }; TreeViewDelegate.Invoke(tree,allFiles [i] .Name); – Ilia

+0

恕我直言,你根本不需要使用'ThreadPool'。只需在UI线程中调用该方法即可。你的方法没有做任何重要的工作。 –

回答

2

由于错误状态,你需要在UI线程上执行UI相关的操作。为了做到这一点,您可以使用控制器本身的BeginInvoke

private void GetFiles(DirectoryInfo directory, TreeNode tree) 
{ 
    if (TreeViewControl.InvokeRequired) 
    { 
     TreeViewControl.BeginInvoke((MethodInvoker)delegate 
     { 
      for (int i = 0; i < allFiles.GetLength(0); i++) 
      { 
       tree.Nodes.Add(allFiles[i].Name); 
      } 
     }); 
    } 
} 

你可以找到更多的信息here

+0

如何在WinForms应用程序中使用Dispatcher? – Ilia

+0

这是WinForms吗?你的标签声明WPF。 –

+0

对不起,我的错 – Ilia

4

我认为你需要做的是:

Dispatcher.CurrentDispatcher.BeginInvoke(new Action(() => GetFiles(directory, tree))); 
+0

欢迎来到Stack Overflow!虽然这段代码可能会回答这个问题,但最好包含一些_context_,解释它的工作原理和_when_使用它。从长远来看,仅有代码的答案是没有用的。 –

+0

Windows窗体中没有'Dispatcher'! – Enigmativity

+0

@Enigmativity当这个答案发布时,问题被标记为[tag:wpf]。 –

相关问题