2013-02-05 83 views
3

任何人都可以告诉我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; 
     } 
    } 
+0

没有你的'else',程序很可能崩溃,那是因为你不能从外部线程改变GUI。由于您需要更改GUI,因此您可以调用该方法。如果没有'else',外部线程会在调用方法后立即尝试更改GUI(导致前面提到的崩溃)。 'InvokeRequired'检查对象是否属于当前线程,基本上这意味着'this.textBox7.Text = text;'永远不会在'textBox7'所属的线程之外的任何线程上运行。 – Nolonar

回答

4
  1. 另一个线程调用的setText
  2. 由于它不是创建它需要Invoke的形成螺纹。
  3. this.Invoke再次使用给定参数调用SetText。同时检查this
  4. 现在的setText从UI线程调用,没有必要调用
  5. else块我们确信文本设置线程安全
+0

谢谢,它确实有帮助! – user1903439

2

InvokeRequired用于检查是否语句在主UI线程或以其他线程比UI线程执行。

如果语句在UI线程之外的其他线程中执行,则使用Invoke不会导致任何CrossThread异常。

+0

谢谢,它真的帮了大忙! – user1903439

2

else是绝对必要的。

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

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

+0

谢谢,它真的帮助! – user1903439

1

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

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

这样,你d o不必在ifelse中都重复您的逻辑。

+0

谢谢,它真的帮助! – user1903439