C# .NET - Window Form C#: Cross-thread operation not valid: Control accessed from a thread other tha

Asked By A S on 03-Jan-14 11:44 AM
Guys,

can you tell me how to fix this code?


I am getting following error: Cross-thread operation not valid: Control accessed from a thread other than the thread it was created on





 here is my code:




//Class Private variables
CountdownEvent _countdownEmployee = new CountdownEvent(2);


void populateDeactivateEmployees(object myForm)
        {

            try
            {
                ComboBox cmbCompany2 = (ComboBox)((Form)myForm).Controls["cmbCompany"];
                ComboBox cmbActivateEmployee2 = (ComboBox)((Form)myForm).Controls["cmbActivateEmployee"];
                {
                    if (cmbActivateEmployee2.Items.Count > 0)
                    {
                        cmbActivateEmployee2.DataSource = null;
                        cmbActivateEmployee2.Items.Clear();
                    }

                    cmbActivateEmployee2.DisplayMember = "employeeName"; // Column Name
                    cmbActivateEmployee2.ValueMember = "employeeId";  // Column Name
                    cmbActivateEmployee2.DataSource = business.food_GetEmployees((string)cmbCompany2.SelectedValue.ToString(), false);





                }

            }
            catch (Exception Ex)
            {
                MessageBox.Show(Ex.ToString());
            }
            finally
            {
                _countdownEmployee.Signal();
            }

        }


        void populateEmployees()
        {
            if (cmbCompany.SelectedValue != null && cmbCompany.SelectedValue.ToString() != "0")
            {
                string companyId = cmbCompany.SelectedValue.ToString();
                Form myForm = this;
                CheckForIllegalCrossThreadCalls = false;
                
                new Thread(populateDeactivateEmployees).Start(myForm);
                new Thread(populateActivateEmployees).Start(myForm);
                _countdownEmployee.Wait();
                
                
            }
        }

        



        void populateActivateEmployees(object myForm)
        {

            try
            {
                ComboBox cmbEmployee2 = (ComboBox)((Form)myForm).Controls["cmbEmployee"];
                ComboBox cmbCompany2 = (ComboBox)((Form)myForm).Controls["cmbCompany"];
                cmbEmployee2.DisplayMember = "employeeName"; // Column Name
                cmbEmployee2.ValueMember = "employeeId";  // Column Name

                DataTable table = business.food_GetEmployees((string)cmbCompany2.SelectedValue.ToString(), true);
                

                if (table.Rows.Count > 0)
                {
                    DataRow dr = table.NewRow();
                    dr["employeeName"] = "Select All";
                    dr["employeeId"] = 0;

                    table.Rows.InsertAt(dr, 0);
                    cmbEmployee2.DataSource = table;


                   



                }

            }
            catch (Exception Ex)
            {
                MessageBox.Show(Ex.ToString());
            }
            finally
            {
                _countdownEmployee.Signal();
            }

        }

Robbe Morris replied to A S on 03-Jan-14 02:37 PM
The UI thread that the controls render on can't be used like you are trying to here.  Why are you launching threads with instances of a form?
A S replied to Robbe Morris on 03-Jan-14 02:50 PM
Robbe,



The reason, I am launching threads with instances of forms, is that so it could have access to UI threads objects and view/add data to those objects.

Is there a way to increase performance? how can we do this?



Robbe Morris replied to A S on 03-Jan-14 03:00 PM
.NET Windows Forms controls are not designed to run across multiple threads. Wish I had a code sample up here for you to look at.  The basic jist for this sort of stuff is that you launch threads to perform some background task and then wire up event handlers as each thread finishes.  In the event handler is where you update your windows forms controls.  The event handler runs on the same thread as the UI controls.

There are some good examples using the BackgroundWorker class or you could also use the thread pool:

http://www.nullskull.com/faq/1488/threadpoolqueueuserworkitem-multithreading-code-sample.aspx