0

I happen to get this Cross-Thread Error when trying to invoke a textbox from a different thread other than the main MMI Thread. I already understand why it happens.I would like your opinion about the way I am solving this. I am using this because I hate adding delegate declarations all over the code.

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

is this the right way to this ? is there a better and shorter way?

Servy
  • 202,030
  • 26
  • 332
  • 449
Yaniv.M
  • 3
  • 2

2 Answers2

0

Nothing wrong with what you've got. If you don't want to make a recursive call, you could just throw an anonymous delegate in the Invoke() call:

private void SetText(string text)
{
    if (this.InvokeRequired)
    {
        this.Invoke((MethodInvoker)delegate
        {
            this.textBox1.Text = text;
        });
    }
    else
    {
        this.textBox1.Text = text;
    }
}
Idle_Mind
  • 38,363
  • 3
  • 29
  • 40
0

That's about the only way to do it, although I would make two changes:

1) Use MethodInvoker so that you can leave out the Func or Action casting, but go ahead and use recursion so that you're not duplicating code.

2) Add a return to the invoke block, so that you don't have the else block. I'd rather add an extra line than have extra indentation.

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

    this.textBox1.Text = text;
}

On second thought you could have a utility method that takes an Action to do the check, and the actual logic would always be inside the lambda.

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;
    });
}
PhilChuang
  • 2,556
  • 1
  • 23
  • 29