-1

Possible Duplicate:
Cross-thread operation not valid: Control accessed from a thread other than the thread it was created on

Below is a method that I've written which attempts to obtain the text from a RichTextControl and return it.

    /** @delegate */
    private delegate string RichTextBoxObtainContentsEventHandler();

    private string ObtainContentsRichTextBox()
    {

        if (richtxtStatus.InvokeRequired)
        {
            // this means we're on the wrong thread!  
            // use BeginInvoke or Invoke to call back on the 
            // correct thread.
            richtxtStatus.Invoke(
                new RichTextBoxObtainContentsEventHandler(ObtainContentsRichTextBox)
                );
            return richtxtStatus.Text.ToString();
        }
        else
        {

            return richtxtStatus.Text.ToString();
        }
    }

However when I attempt to run this I get the following exception: Cross-thread operation not valid: Control 'richtxtStatus' accessed from a thread other than the thread it was created on.

How can I modify the above code to allow me to return the contents?

Community
  • 1
  • 1
Brad
  • 1,979
  • 7
  • 35
  • 47
  • 2
    Did you try searching here on SO for this already? Can't count how many times I have seen this question. – Bryan Crosby Apr 10 '12 at 22:21
  • I've been searching SO for an example of returning a value when using .Invoke and I've not found any posts that mimic the situation above but I am admittedly a csharp novice so maybe I'm just not understanding/seeing what I need to do. – Brad Apr 10 '12 at 22:24
  • @dlev - If I don't then I get: Not all code paths return a value. – Brad Apr 10 '12 at 22:31
  • @Brad, you can still return richtxtStatus.Text.ToString() in the `else` clause since it does not require an invoke – Tung Apr 10 '12 at 22:37
  • @Brad One issue at a time. A syntax error, of course, takes precedence over a runtime error. –  Apr 10 '12 at 23:01

1 Answers1

4

The problem is that you are still accessing the text box on the wrong thread. You need to return the result of the Invoke(), rather than just invoking, ignoring the result, and then doing the very thing you were trying to avoid in the first place. Also, you don't need to wrap it in an event handler; just invoke the current method again.

if (richtxtStatus.InvokeRequired)
{
    // this means we're on the wrong thread!  
    // use BeginInvoke or Invoke to call back on the 
    // correct thread.
    string text = (string)richtxtStatus.Invoke(ObtainContentsRichTextBox);
    return text;
}

Finally, .Text is already a string, so there's no need to call .ToString() on it. It can be returned directly.

dlev
  • 48,024
  • 5
  • 125
  • 132