C#-无法使用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

您好,我在从C#中的工作线程调用richTextBox时遇到问题。我正在使用invokererequired/Invoke方法。请查看我的代码:

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