Click here to Skip to main content
15,867,835 members
Please Sign up or sign in to vote.
1.00/5 (1 vote)
See more:
i am a newer c# programmer and i dont know how to work my serach result in my accourding error

I keep getting the following error when debugging.


C#
Cross-thread operation not valid: Control 'txtDataRx' accessed from a thread other than the thread it was created on.


Here's the code that it points to:


C#
public  void OnDataReceived(IAsyncResult asyn)
    {
        try
        {
            CSocketPacket theSockId = (CSocketPacket)asyn.AsyncState ;
            //end receive...
            int iRx  = 0 ;
            iRx = theSockId.thisSocket.EndReceive (asyn);
            char[] chars = new char[iRx +  1];
            System.Text.Decoder d = System.Text.Encoding.UTF8.GetDecoder();
            int charLen = d.GetChars(theSockId.dataBuffer, 0, iRx, chars, 0);
            System.String szData = new System.String(chars);
            txtDataRx.Text = txtDataRx.Text + szData;
            WaitForData(m_socWorker );
        }
        catch (ObjectDisposedException )
        {
            System.Diagnostics.Debugger.Log(0,"1","\nOnDataReceived: Socket has been closed\n");
        }
        catch(SocketException se)
        {
            MessageBox.Show (se.Message );
        }
    }



Can somebody please help me fix this?
please!!!!!!!
Posted

You are updating a UI control from a different thread.

instead of updating it directly,

C#
txtDataRx.Text = txtDataRx.Text + szData;


instead use a delegate,

e.g define a delegate

C#
delegate void UpdateTextBoxCallBack(TextBox txtBox, string strText);


create a method, to update this text box as shown below.

C#
public void UpdateTextBox (TextBox txtBox, string strText)
{
      if (txtBox.InvokeRequired)
      {
          UpdateTextBoxCallBack upcb = new UpdateTextBoxCallBack(UpdateTextBox);
          this.Invoke(upcb, new object[] { txtBox, strText});
      }
      else
      {
           txtBox.Text = strText ;
      }
}



and when you need to update this text box from some other thread. just call the method

C#
UpdateTextBox (txtBox, "New Text to be updated" );  


hope this helps.

-praveen.
 
Share this answer
 
Comments
Sergey Alexandrovich Kryukov 8-Jul-14 3:07am    
Voted 4. Some notes:

First, InvokeRequired is redundant in almost all cases. It is only needed for methods which are sometimes called in UI thread and sometime is some other thread. If the thread is (the same) UI thread, invocation is always requires, and not required otherwise.

Then, definition of delegate type is also redundant, because the set of generic types System.Action already solves it.

—SA
You can only access the control from the thread where it was created(that is, the UI thread). In other threads(like your BackgroundWorker), you need to use Control.BeginInvoke[^] or Control.Invoke[^].

Replace your following code
C#
txtDataRx.Text = txtDataRx.Text + szData;

with
C#
this.BeginInvoke(new MethodInvoker(delegate()
{
   this.txtDataRx.AppendText(szData);
}));

and then try if it works.

Good luck
 
Share this answer
 
v3
Comments
Sergey Alexandrovich Kryukov 8-Jul-14 3:04am    
Not quite true. It could be either Control.Invoke or Control.BeginInvoke.
—SA
Raje_ 8-Jul-14 3:12am    
Thanks for pointing this out. I appreciate this. I have updated my solution.
Sergey Alexandrovich Kryukov 8-Jul-14 3:17am    
Up-voted... :-)
—SA
Raje_ 8-Jul-14 3:23am    
Thank you.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900