I\'m writing chat client/server app with c# and I have problem with threading. I wrote this simple code for showing my problem.
I used thread_1 for showing Form but
As Linkerro mentioned, you want to take out the thread you call Thread 1 as your UI will already be in a thread when you start (all programs have a single main thread they start on). You were on the right track though, you want to put any long-running tasks on a separate thread so it doesn't block the UI. The only trick is you cannot directly maniuplate UI objects from background threads, they must be manipulated from the thread that owns them (which is the error message you are getting is saying).
Luckily there is a very easy way to accomplish this in .NET. In WPF you use UiComponent.Dispatcher.Invoke() and Winforms just use UiComponent.Invoke(). This allows your background thread to step over to the thread where the UI component lives to update it.
Invoke takes a delegate which represents the action you would like to run on the UI thread. In my example I pass in an action which is initialized using a lambada expression, taking no parameters and returning no value.
Try this
private void doThread2()
{
try
{
for (int j = 10000; j > 0; j--)
{
textBox.Invoke(new Action(() =>
textBox.Text = j.ToString()));
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
Here is a full example of how you can do this with Tasks. You will see while it is counting you can freely move the window around and it does not lock up. However take out the Task and leave the loop and you will see how the window freezes since the loop would then block the UI thread.
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
Task.Factory.StartNew(() =>
{
for (int x = 0; x < 100000000; x++)
{
label1.Invoke(new Action(() =>
label1.Text = x.ToString()));
}
});
}
}