change the text of a label while a thread is running

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • kspiros
    New Member
    • Oct 2008
    • 16

    change the text of a label while a thread is running

    i can not find a way in order to change a label while this tread is running
    Code:
    public void work()
            {
                ///////
                
                int[] d = new int[5];
                Thread.Sleep(draw_delay);
                    for (int i = 0; i < 5; i++)
                    {
                        d[i] = 0;
                        double a;
                        a = Math.Sqrt(Math.Pow(pointcheck[0] - X[i], 2) + Math.Pow(pointcheck[1] - Y[i], 2));
                        d[i] = Convert.ToInt32(a);
                    }
                    myTempMap = ptuxiaki.Properties.Resources.map;
                    if (Math.Abs(d[0]) < R[0])
                    {
                       UpdateWiMax_enable();// This method will draw an ellipse for the WiMax signal
    
                    }
                    else {
                        UpdateWiMax();
                    }
                    if (Math.Abs(d[1]) < R[1])
                    {
                        UpdateUMTS_enable();// you get the drift                        
                    }
                    else
                    {
                        UpdateUMTS();
                    }
                    if (Math.Abs(d[2]) < R[2])
                    {
                        UpdateCPC_enable();
                    }
                    else
                    {
                        UpdateCPC();
                    }
                    if (Math.Abs(d[3]) < R[3])
                    {
                        UpdateGPRS_enable();
                    }
                    else
                    {
                        UpdateGPRS();
                    }
                    if (Math.Abs(d[4]) < R[4])
                    {
                        UpdateWiFi_enable();
                    }
                    else
                    {
                        UpdateWiFi();
                    }
                        pictureBox_Map.Image = myTempMap;
                        myTempMap = null;
    
            }
    if i do this
    Code:
    if (Math.Abs(d[0]) < R[0])
                    {
                       UpdateWiMax_enable();
    label.text="something";
    
                    }
    I get the error that Cross-thread operation not valid: Control 'label' accessed from a thread other than the thread it was created on. who can i solve this?
  • mldisibio
    Recognized Expert New Member
    • Sep 2008
    • 191

    #2
    WinForms UI Thread Invokes
    MSDN BackgroundWorke r
    Authoring MultiThreaded Components
    You cannot update or modify a control property from any other thread other than the thread the control was created on.

    To make sure you are on the correct thread, you use the Invoke method of the control to perform the update.

    The preferred threading model for Windows Forms threading is provided by the BackgroundWorke r component.

    Comment

    • balabaster
      Recognized Expert Contributor
      • Mar 2007
      • 798

      #3
      Okay, if you're familiar with delegates, this is a breeze... if not, this is going to take some getting your head around.

      If you want to post data to the main thread from another, then you have to post through a delegate method - think of a delegate method as a placeholder for the memory address of a method. We put the address of the method we wish to run into the delegate which then sits and waits to be called. At whatever point the delegate is called - it fires whatever method sits at the address stored in its buffer.

      It's been a while since I had to do this, but the following code is close enough to point you in the right direction...

      VB.NET
      Code:
      Public Delegate Sub SetLabelTextDelegate(ByVal LabelObject As Label, ByVal Value As String)
      
      Public Sub SetLabelText(ByVal LabelObject As Label, ByVal Value As String)
      
        If LabelObject.InvokeRequired Then
          Dim dlg As New SetLabelTextDelegate(AddressOf SetLabelText)
          dlg.Invoke(LabelObject, Value)
        Else
          LabelObject.Text = Value
        End If
      
      End Sub
      C#
      Code:
      public delegate void SetLabelTextDelegate(Label LabelObject, string Value);
      
      public void SetLabelText(Label LabelObject, string Value) 
      { 
          if (LabelObject.InvokeRequired) { 
              SetLabelTextDelegate dlg = new SetLabelTextDelegate(SetLabelText); 
              dlg.Invoke(LabelObject, Value); 
          } 
          else { 
              LabelObject.Text = Value; 
          } 
      }
      So where you would normally make a call like Label1.Text = "Stuff", you would now make the following call: SetLabelText(My LabelObject, "Text to put in my label").

      This will now post text from the secondary thread properly... in my applications, I usually create this pattern for each type of object I have on screen that will required updating from any thread and all calls to set the values will go through the SetxxxValue method (regardless of which thread I'm posting from, for consistency), which will pass the object to be updated and the text to put into it.

      Comment

      • kspiros
        New Member
        • Oct 2008
        • 16

        #4
        Thanks guys i solve it with this
        Code:
         
        //Declare a new delegate specific to updating the text of a label         
        delegate void UpdateLabelTextDelegate(Label lbl, string text);
                  //This method will invoke the delegate and pass our args along         
        void UpdateLabelText(Label lbl, string text)        
         {             
        UpdateLabelTextDelegate dlg = new UpdateLabelTextDelegate(UpdateLabelTextByDelegate);             
        //Invoke this method on the control's original that owns the label's //handle             
        lbl.Invoke(dlg, new object[] { lbl, text });        
         }         
         //This method is invoked by our delegate and actually updates the label //text         
        void UpdateLabelTextByDelegate(Label lbl, string text)        
         {            
         lbl.Text = text;         
        }
        Thanks a lot!!!

        Comment

        Working...