2017-06-09 198 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; 
    }); 
}