-2

I have two classes(Data_Reader And Display_Data) and a GUI_Form.
What i want is to Display the Read data of Data_Reader Class on Textbox which exists on GUI_Form so to wrap it i wrote Display_Data class .
But i got the folowing exception:

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

Can anyone knows how to solve this ? I just Want to update Read Data values on GUI Form.

//    Gui Form
//    ============
public partial class GUI_Form: Form
{
}
//    ==============
//    Display Data Class
//    ===========
public static class Display_Data
{
    public delegate void MyDelegate(Label myControl, string myArg2);
    public static void DelegateMethod(Label myControl, string myCaption)
        {
            myControl.Text = myCaption;
        } 
}

//=========================
//  Reader Class
//=========================
public void Data_Reader
{
    string Data_Received_text="Test";
    private System.ComponentModel.ISynchronizeInvoke _syn;
    Meter_Data_Class.packets_received_counter_status_display++;
    //it will call the display_Data class delegate method to update textbox on gui
    syn.BeginInvoke(new
                  Display_Data.MyDelegate(Display_Data.DelegateMethod),Data_Received_text);

}
Zohar Peled
  • 79,642
  • 10
  • 69
  • 121

2 Answers2

0

Use textBox1.BeginInvoke() for invoke the delegate.

Nakul Chaudhary
  • 25,572
  • 15
  • 44
  • 47
0

You can't use the methods or properties of UI controls from a thread that is not the UI thread directly. This is why you get that exception. In order to overcome this obstacle, you need to invoke a delegate from the different thread that will do the UI change for you. the Control class in System.Windows.Forms namespace includes a property called InvokeRequired that tells you if the current thread is the UI thread or a different thread. If it's the UI thread you can use the properties and methods of the control. If it's not the UI thread, you must invoke a delegate to do use the properties and methods of the control. Here is a simple methods that is based on your existing delegate in the code you published:

public static void DelegateMethod(Label myControl, string myCaption)
    {
    // Calling from another thread? -> Use delegate
    if (myControl.InvokeRequired) {
        MyDelegate d = new MyDelegate(DelegateMethod);
        // Execute delegate in the UI thread, pass args as an array
        this.Invoke(d, new object[] {
            myControl,
            myCaption
        });
    // Same thread, assign string to the textbox
    } else {
        myControl.Text = myCaption;
    }
}
Zohar Peled
  • 79,642
  • 10
  • 69
  • 121
  • Could you explain this please? – Rakshith Ravi Jun 12 '15 at 16:49
  • So why are you setting the `Text` property of `myControl` in the beginning of the function when you don't even know if you are on the same thread? – Rakshith Ravi Jun 13 '15 at 08:43
  • 1
    Oops, thanks for catching that. It was a mistake. I've copied this answer from another one I gave to someone else in vb.net, and it must have been left there as a leftover from multiple copy-paste operations. Anyway, I've edited my answer to remove that part. – Zohar Peled Jun 13 '15 at 08:58