跨线程操作

时间:2013-02-05 09:49:51

标签: c# multithreading

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

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;
        }
    }

4 个答案:

答案 0 :(得分:4)

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

答案 1 :(得分:2)

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

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

答案 2 :(得分:2)

else绝对是必要的。

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

如果没有在UI线程上完成,那么盲目前进this.textBox7.Text会导致异常。

答案 3 :(得分:1)

只是为了添加其他答案,这是一种常见模式(特别是在被调用方法包含大量逻辑的情况下) - 如果InvokeRequired返回true,则从UI线程调回相同的方法:

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

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