Click here to Skip to main content
15,884,473 members
Please Sign up or sign in to vote.
1.00/5 (1 vote)
See more:
Hi guys ,
im trying to show splash screen but the following error is shown:

Cross-thread operation not valid: Control 'cmbEnviroment' accessed from a thread other than the thread it was created on



this is my code for the threading :

private void LoadInstitutions()
      {
          //Thread.Sleep(3000);

          // OperationClass oc = new OperationClass();
          // oc.loading();
          string selectedValue = cmbEnviroment.SelectedItem.ToString().Trim();
          ConnectionClass connectionClass = new ConnectionClass();
          connectionClass.Connection(selectedValue);

          DataTable table4 = new DataTable();

          string sql4 = "A query to gather data";

          try
          {

              OleDbDataAdapter da4 = new OleDbDataAdapter(sql4, connectionClass.Connection(selectedValue));
              da4.Fill(table4);
              DataRow dr4 = table4.NewRow();
              DataRow dr5 = table4.NewRow();
              dr4["hello1"] = "";
              table4.Rows.InsertAt(dr4, 0);

              cmbInstitution.DataSource = table4;
              cmbInstitution.DisplayMember = "hello1";
              cmbInstitution.ValueMember = "hello1";
          }
          catch (Exception ex)
          {
              MessageBox.Show(ex.ToString());
          }





      }

      private async void cmbEnviroment_SelectedIndexChanged(object sender, EventArgs e)
      {

          //using (new PleaseWait(this.Location))
          //{
              ComboBox senderComboBox = (ComboBox)sender;
              if (senderComboBox.SelectedIndex > 0)
              {
                  LoadingScreen ls = new LoadingScreen();
                  ls.TopMost = true;
                  ls.Show();

                  await Task.Run(() => LoadInstitutions());

                  ls.Close();
               }
          //}

      }


What I have tried:

im have tried different methods to show the splash screen while i'm gathering data from database but im stuck .
Posted
Updated 27-Jun-18 4:50am

You cannot access any control from any thread other than the UI thread - when you try, you get a "cross thread exception" as you are seeing.

Two ways to fix this:
1) Invoke the control instead of accessing it directly: Control.Invoke Method (Delegate) (System.Windows.Forms)[^]
2) Move your long running code into a background thread using the BackgroundWorker class which is designed to provide progress information to the UI thread for updates.
 
Share this answer
 
Comments
Joe Doe234 27-Jun-18 3:45am    
hi original , thanks for answer my question :). small question
i did this to my long running code :

this.Invoke((MethodInvoker)delegate ()
{ ...

this is working perferctly but the animated gif is not working. it will just appear.
Refactor your code to move the long-running part to a background thread, and keep the parts that access the UI on the UI thread:
C#
private static DataTable LoadInstitutions(string selectedValue)
{
    ConnectionClass connectionClass = new ConnectionClass();
    const string sql = "A query to gather data";
    
    DataTable result = new DataTable();
    OleDbDataAdapter da = new OleDbDataAdapter(sql, connectionClass.Connection(selectedValue));
    da.Fill(result);
    
    DataRow dr = result.NewRow();
    dr["hello1"] = "";
    result.Rows.InsertAt(dr, 0);
    
    return result;
}

private async Task LoadInstitutions()
{
    try
    {
        string selectedValue = cmbEnviroment.SelectedItem.ToString().Trim();
        DataTable table = await Task.Run(() => LoadInstitutions(selectedValue));
        cmbInstitution.DataSource = table4;
        cmbInstitution.DisplayMember = "hello1";
        cmbInstitution.ValueMember = "hello1";
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.ToString());
    }
}

private async void cmbEnviroment_SelectedIndexChanged(object sender, EventArgs e)
{
    ComboBox senderComboBox = (ComboBox)sender;
    if (senderComboBox.SelectedIndex > 0)
    {
        LoadingScreen ls = new LoadingScreen();
        ls.TopMost = true;
        ls.Show();
        try
        {
            await LoadInstitutions();
        }
        finally
        {
            ls.Close();
        }
    }
}
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900