2017-06-09 138 views
0

当尝试从主MMI线程以外的其他线程调用文本框时,碰巧发生此跨线程错误。我已经明白了为什么会发生。我希望你对我解决这个问题的看法有所意见。 我使用这个,因为我讨厌在代码中添加委托声明。跨线程操作

private void SetText(string text) 
{   
    if (textBox1.InvokeRequired) 
    { 
     this.Invoke(new Action<string>(SetText), new object[]{ text }); 
    } 
    else 
    { 
     this.textBox1.Text = text; 
    } 
} 

这是正确的方法吗? 有没有更好更短的方法?

回答

0

没有错,你有什么。如果你不想做一个递归调用,你可能只是抛出一个匿名委托在Invoke()电话:

private void SetText(string text) 
{ 
    if (this.InvokeRequired) 
    { 
     this.Invoke((MethodInvoker)delegate 
     { 
      this.textBox1.Text = text; 
     }); 
    } 
    else 
    { 
     this.textBox1.Text = text; 
    } 
} 
0

这是对只有这样,才能做到这一点,但我会做两个修改:

1)使用MethodInvoker,这样你就可以省去Func或者Action的操作,但是继续使用递归,这样你就不会复制代码。

2)向invoke块添加一个返回值,这样就没有else块。我宁愿添加额外的行,而不是额外的缩进。

private void SetText(string text) 
{   
    if (textBox1.InvokeRequired) 
    { 
     this.Invoke((MethodInvoker) delegate { SetText(text); }); 
     return; 
    } 

    this.textBox1.Text = text; 
} 

关于第二个想法,你可以有个实用方法需要一个动作做检查,和实际的逻辑将永远是拉姆达内。

private static void InvokeIfRequired(bool required, Action action) { 
    // NOTE if there is an interface which contains InvokeRequired 
    //  then use that instead of passing the bool directly. 
    //  I just don't remember off the top of my head 
    if (required) { 
     this.Invoke((MethodInvoker) delegate { action(); }); 
     return; 
    } 

    action(); 
} 

private void SetText(string text) 
{ 
    InvokeIfRequired(textBox1.InvokeRequired,() => { 
     this.textBox1.Text = text; 
    }); 
}