Greetings, I’m having problem invoking a richTextBox from a worker thread in C#. I’m using the InvokeRequired/Invoke method. Please see my code:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void ThreadSafe(MethodInvoker method)
{
if (InvokeRequired)
Invoke(method);
else
method();
}
private void WorkerThread(object data)
{
string msg = "\nhello, i am thread " + data.ToString();
ThreadSafe(delegate
{
richTextBox1.AppendText(msg);
});
}
private void button1_Click(object sender, EventArgs e)
{
Thread[] workers = new Thread[3];
for (int i = 0; i < 3; i++)
{
workers[i] = new Thread(WorkerThread);
workers[i].Start(i);
string msg = "\nthread " + i.ToString() + "started!";
richTextBox1.AppendText(msg);
}
int j = 3;
while (j > 0)
{
for (int i = 0; i < 3; i++)
{
Thread.Sleep(250);
richTextBox1.AppendText("\nChecking thread");
if (workers[i].Join(250))
{
string msg = "\nWorker thread " + i.ToString() + " finished.";
richTextBox1.AppendText(msg);
workers[i] = null;
j--; // decrement the thread watch count
}
}
}
}
}
It prints the following in the rich text box:
thread 0started!
thread 1started!
thread 2started!
Checking thread
Checking thread
Checking thread
Checking thread
....
It goes on and on, the “hello” message doesn’t get printed, and the UI is frozen.
Then I changed Invoke() to BeginInvoke(), which I know I shouldn’t do, then the result is like this:
thread 0started!
thread 1started!
thread 2started!
Checking thread
Worker thread 0 finished.
Checking thread
Worker thread 1 finished.
Checking thread
Worker thread 2 finished.
hello, i am thread 0
hello, i am thread 1
hello, i am thread 2
What is the reason and what do I do?
Thanks in advance.
You are waiting for the worker threads to complete before leaving your
button1_Clickmethod. This is a problem because your threads can’t complete until they are able to run the delegate that calls theAppendTextmethod on that same thread.When you change to
BeginInvokeyou don’t have this problem any more because your worker threads don’t block waiting on the delegate that calls theAppendTextmethod.If you are trying to block the UI thread until the worker threads complete you simply will not be able to as long as they rely on the call to
Invoke.