2017-06-09 5 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

何があっても間違っていません。

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

私は2つの変更を加えるだろうが、それを行うための唯一の方法についてです:

をあなたは再帰呼び出しをしたくない場合は、あなただけの Invoke()呼び出しで匿名デリゲートを投げることができ

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; 
    }); 
} 
関連する問題