C# – How to fix “Action being performed on this control is being called from the wrong thread”?
August 2, 2019
When we populate the data in the control, if the data is big, usually we put the data population logic in the thread to execute it asynchronously. We need to be cautious when we do this data population from another thread. Because, we can not use the controls directly in different threads. This has to be marshaled properly before we pass the control between the threads. If we miss to do this properly, we will see below Error message;
TreeView - Demo
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.
Through this article, we are going to discuss how to reproduce this error using TreeView control and also discuss how to fix this.
Reproducing the above error
Step 1. Create a C# Windows Forms Application and place a TreeView control on the Form.
Step 2. Let’s populate the random values in the control. And the population logic, we will place in a thread. The code looks like below;
Task task = Task.Run( () => PopulateData());
private void PopulateData()
Random rand = new Random();
TreeNode node = treeViewControl.Nodes.Add("Parent");
for (int i = 0 ; i < 10000 ; i++ ) // some kind of long operation
Step 3. Run the program and you will see the above Error message; as we are using separate thread to populate the data. Better way is, caught the exception, and display the message; it looks like below.
How to fix the above issue?
Step 4. We will use control’s BeginInvoke() method to populate the data asynchronously; instead of putting the data population logic to run in a separate thread. This method is a thread safe; it properly handles the marshaling, hence we can use this method in our sample to populate the data.
One variance of BeginInvoke() method, takes delegate as an argument. So, we will invoke this method to invoke the data population logic and we pass delegate as an argument. The delegate will points to the function where we placed data population logic; in this example, it is PopulateData() method.
We re-write the above code as below;
public delegate void FunctionDelegate();
Step 5. Now, re-run the program and observe that; the program successfully compiled and populate the data in the TreeView control. The screenshot of it, looks like below;
Necessary cookies are absolutely essential for the website to function properly. This category only includes cookies that ensures basic functionalities and security features of the website. These cookies do not store any personal information.
Any cookies that may not be particularly necessary for the website to function and is used specifically to collect user personal data via analytics, ads, other embedded contents are termed as non-necessary cookies. It is mandatory to procure user consent prior to running these cookies on your website.