Click here to Skip to main content
15,885,757 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hi
I've a class derived from form called "BaseForm1". It looks like

C#
public class BaseForm1 : Form
{

   public BaseForm1()
{
}
 protected override void OnLoad(EventArgs e)
{
  base.OnLoad(e);
  Thread t = new Thread(new ThreadStart(Init));
  t.Start();
}

public void Init()
{
/* This function do some work on form load such as clearing text boxes ,
loading data to combobox etc.

Calling this function makes the form load slowly. So I called it in new thread

*/
}

}


I have another class inherits from the above class

In this class I overrides the function "Init()"


like

C#
public override void Init()
{
base.Init();

textbox1.Text = "Some Text";
 CallSomeFunction();
}



When this code executes following error occures

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


I Created the following function to call the init
C#
private void CallInit()
       {
           this.Invoke(new MethodInvoker(delegate()
           {
               Init();
           }));
       }

and tried to start the thread like below
C#
protected override void OnLoad(EventArgs e)
     {
         base.OnLoad(e);
         Thread t = new Thread(new ThreadStart(CallInit));
         t.Start();
     }


and also tried BackgroundWorker

DoWork() also gives the same error

RunWorkerCompleted() not gives the required performance

please help !
Posted

1 solution

Thread operations on UI objects have to be performed on the UI thread. You get the error because you are creating the thread in the base class which calls the derived method init routine.

For each of the textboxes, you should do something like this:

C#
myTextBox.Invoke((MethodInvoker) delegate { myTextBox.Text = string.Empty; });


You can check if invoke is required but if you are running on a separate thread then it will be (use the myTextBox.InvokeRequired to see if you have to do the above).

It begs the question though, do you have so many text boxes on one form that your initialization routine has to be threaded? Why not set them to the defaults in the designer? If it takes that long to initialize your form, maybe you want to think about breaking it up into logical pieces that can be loaded when needed.
 
Share this answer
 
Comments
Jackson K T 13-Sep-13 9:13am    
My initialization routine need to be threaded because it's done using reflection so that in the inherited form you won't need to write initialization .
Ron Beyer 13-Sep-13 9:18am    
Not sure why you'd need reflection, you can loop through controls on derived forms using the Controls collection, and use type checking to find out what kind of control it is and initialize it properly. I've done this many times, if you post your reflection code, I can see if it can be converted to non-reflection which I'm pretty sure it can. Avoid reflection like the plague.
Jackson K T 13-Sep-13 9:32am    
public static void ClearControls(Control FormName)
{

try
{
foreach (Control Obj in FormName.Controls)
{

if (Obj.HasChildren == true)
{
ClearControls(Obj);
if (Obj is Gramboo.Controls.GrbRadioButtonGroup)
{
((Gramboo.Controls.GrbRadioButtonGroup)Obj).Value = "";
}
else if (Obj is Gramboo.Controls.GrbDataGridView)
{
if (((Gramboo.Controls.GrbDataGridView)Obj).IsList == false)
((Gramboo.Controls.GrbDataGridView)Obj).DataSource = null;
}
}
else if (Obj is TextBox)
{
((TextBox)Obj).Text = "";
}
else if (Obj is ComboBox)
{

((ComboBox)Obj).Text = "";
((ComboBox)Obj).SelectedIndex = -1;
}
else if (Obj is DateTimePicker)
{
((DateTimePicker)Obj).Value = DateTime.Now.Date;
}
else if (Obj is CheckBox)
{
((CheckBox)Obj).Checked = false;
}
else if (Obj is RadioButton)
{
((RadioButton)Obj).Checked = false;

}
else if (Obj is MaskedTextBox)
{
((MaskedTextBox)Obj).Text = "";
}

}
}
catch (Exception ex)
{
ShowMessage(ex.Message, "", MessageBoxIcon.Error);
}
}
Ron Beyer 13-Sep-13 9:54am    
None of that is reflection, so it should not take that much time to go through...

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