hello,
I try to use the Form Controls multithreaded call, the following error occurred:
Inter-thread operation not valid: access it from not create controls "textBox2" thread.
My codes:
private void btnMT_Click(object sender, EventArgs e) {
MessageBox.Show("Now,You still can do some other things.");
SetEnabledForFalse();
Thread t_one = new Thread(new ThreadStart(FunOne));
Thread t_two = new Thread(new ThreadStart(FunTwo));
t_one.Start();
t_two.Start();
SetEnabledForTrue();
}
private void FunOne() {
for (int i = 0; i < 100; i++)
{
textBox1.AppendText(i.ToString()+" ");
Thread.Sleep(500);
}
}
private void FunTwo() {
for (int i = 0; i < 100; i++)
{
textBox2.AppendText(i.ToString() + " ");
Thread.Sleep(500);
}
}
private void SetEnabledForTrue() {
textBox1.Enabled = true;
textBox2.Enabled = true;
btnMT.Enabled = true;
}
private void SetEnabledForFalse(){
textBox1.Enabled = false;
textBox2.Enabled = false;
btnMT.Enabled = false;
}
private void btnOther_One_Click(object sender, EventArgs e){
MessageBox.Show("This btnOther_One_Click,Working...");
}
private void btnOther_two_Click(object sender, EventArgs e){
MessageBox.Show("This btnOther_two_Click,Working...");
}
Thanks.
Loading

VulpesPosted Feb 19, 2014, 11:42 AM
Now you are, then this method will also be running on the same (non-UI) thread and the same considerations will apply to setting the Enabled property of controls within that method.
When you create your own threads, they are foreground threads by default and will therefore keep running when the main UI thread stops. To avoid this, you can make them into background threads after you've created them and just before starting them:
t_one.IsBackground = true;
t_two.IsBackground = true;
If you don't like having to marshal back to the UI thread all the time, you can use a BackgroundWorker instead of creating your own threads. This allows opportunities for communicating with the UI thread without the need for Invoke:
http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker(v=vs.110).aspx
Ken HPosted Feb 19, 2014, 10:22 AM
First:
private void FunOne()
{
for (int i = 0; i < 100; i++)
{
if(textBox1.InvokeRequired) // if not on UI thread
{
textBox1.Invoke((Action)(() => textBox1.AppendText(i.ToString() + " ")));
}
else // no need for invoke
{
textBox1.AppendText(i.ToString() + " ");
}
Thread.Sleep(500);
}
SetEnabledForTrue(); // My original intention was to want it finished and then restore the control state.
}
Second:
When the thread is not completed and executed form is closed, an error is thrown.
However, We must take full account of the needs of users, that is, We allow the user to advance to close it.
VulpesPosted Feb 19, 2014, 6:47 AM
When you're on a different thread, you can marshal control accesses back to the UI thread using the Invoke (or BeginInvoke) methods.You can also check whether Invoke is required or not with the InvokeRequired property.
I've therefore altered your Fun1 and Fun2 methods to allow for the possibility that they are being called from a different thread: