5

I have a multithreading app, and I need to add object from another thread to the treeview. But I keep getting an exception

Action being performed on this control is being called from the wrong thread. Marshal to the correct thread using Control.Invoke or Control.BeginInvoke to perform this action.

Here is my code

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);
    }
}
4
  • 1
    This is a standard message, You cannot modify elements created by the UI-thread from a non ui thread. Use BeginInvoke() with an anonymous delegate or an usual delegate on the mainform from Your thread. I think, lambda and linq even offer better methods. Commented Mar 21, 2016 at 17:01
  • i doing with a help of delegate, but still recieve an exception public delegate void MyDelagate(TreeNode tree, string value); public MyDelagate TreeViewDelegate; TreeViewDelegate = delegate(TreeNode tree, string s) { tree.Nodes.Add(s); };TreeViewDelegate.Invoke(tree,allFiles[i].Name); Commented Mar 21, 2016 at 17:12
  • IMHO you don't need to use ThreadPool at all. Just call the method in UI thread. Your method isn't doing any significant work. Commented Mar 21, 2016 at 17:12
  • Read the exception message, the answer is there. Commented Mar 21, 2016 at 17:40

2 Answers 2

5

As the error states, you need to perform UI related actions on the UI thread. In order to do this, you can use BeginInvoke from the control itself.

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);
            }
        });
    }
}

You can find more information here.

Sign up to request clarification or add additional context in comments.

Comments

4

I think you need to do this:

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.