C#-无法使用Invoke()从后台线程向控件追加文本
您好,我在从C#中的工作线程调用richTextBox时遇到问题。我正在使用invokererequired/Invoke方法。请查看我的代码:C#-无法使用Invoke()从后台线程向控件追加文本,c#,multithreading,user-interface,controls,invoke,C#,Multithreading,User Interface,Controls,Invoke,您好,我在从C#中的工作线程调用richTextBox时遇到问题。我正在使用invokererequired/Invoke方法。请查看我的代码: public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void ThreadSafe(MethodInvoker method) { if (InvokeRequ
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
}
}
}
}
}
它持续不断,“hello”消息无法打印,UI被冻结。
然后我将Invoke()更改为BeginInvoke(),我知道我不应该这样做,结果如下:
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
原因是什么?我该怎么办
提前感谢。您不能从另一个线程更新UI控件,您不能从另一个线程更新UI控件,您正在等待工作线程完成,然后离开
按钮1\u单击
方法。这是一个问题,因为线程只有在能够在同一线程上运行调用AppendText
方法的委托时才能完成
当您更改为BeginInvoke
时,您不再有此问题,因为工作线程不会阻止调用AppendText
方法的代理的等待
如果您试图在工作线程完成之前阻止UI线程,那么只要它们依赖于调用
Invoke
您在离开按钮1\u单击方法之前等待工作线程完成,您就无法阻止UI线程。这是一个问题,因为线程只有在能够在同一线程上运行调用AppendText
方法的委托时才能完成
当您更改为BeginInvoke
时,您不再有此问题,因为工作线程不会阻止调用AppendText
方法的代理的等待
如果您试图在工作线程完成之前阻止UI线程,那么只要它们依赖于对Invoke
的调用,Invoke
方法同步运行您的委托,它将等待UI线程实际运行它,然后再将控制权返回给调用方。
由于UI线程正在等待线程完成,因此会出现死锁
相比之下,BeginInvoke
方法异步运行您的委托,它会立即返回,委托只会在UI线程空闲时运行一段时间 Invoke
方法同步运行委托,直到UI线程实际运行委托,然后再将控制权返回给调用方。
由于UI线程正在等待线程完成,因此会出现死锁
相比之下,BeginInvoke
方法异步运行您的委托,它会立即返回,委托只会在UI线程空闲时运行一段时间 他知道这一点。读这个问题,他知道。阅读问题。
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