跨线程操作

本文关键字:操作 线程 | 更新日期: 2023-09-27 17:57:35

有人能告诉我if和else语句在这个函数中是如何关联的吗。我正在显示从另一个线程到GUI线程的文本。执行的顺序或方式是什么。其他陈述有必要吗?

delegate void SetTextCallback(string text);
    private void SetText(string text)
    {
        // InvokeRequired required compares the thread ID of the
        // calling thread to the thread ID of the creating thread.
        // If these threads are different, it returns true.
        if (this.textBox7.InvokeRequired)
        {
            SetTextCallback d = new SetTextCallback(SetText);
            this.Invoke(d, new object[] { text });
        }
        else
        {
            this.textBox7.Text = text;
        }
    }

跨线程操作

  1. 另一个线程调用SetText
  2. 由于它不是创建表单的线程,因此它需要Invoke
  3. this.Invoke再次调用具有给定参数的SetText。还要检查这个
  4. 现在从UI线程调用SetText,不需要调用
  5. else块中,我们确信文本被安全地设置为线程

InvokeRequired用于检查语句是在主UI线程中执行还是在UI线程以外的其他线程中执行。

如果语句是在UI线程以外的其他线程中执行的,则Invoke用于不引起任何CrossThread异常。

else是绝对必要的。

此代码所做的是允许您从任何线程安全地调用SetText。如果从UI线程(if块)以外的线程调用它,它会透明地将调用转发到UI线程(else块),后者是唯一可以访问控件以读取或设置其文本的线程。

如果不在UI线程上执行,盲目地执行this.textBox7.Text将导致异常。

添加到其他答案中,这是一种常见的模式(尤其是在被调用方法包含大量逻辑的场景中)-如果InvokeRequired返回true,则从UI线程回调到同一方法:

private void SetText(string text)
{
    if (InvokeRequired)
        BeginInvoke(new Action<string>((t) => SetText(text)));
    else
        textBox7.Text = text;
}

这样,您就不必在ifelse中重复您的逻辑。