0

I keep getting this error while debugging the code. I am new to programming and I have tried solutions which have already stated for similar problems and still I can not solve the problem.

The exception being thrown is:

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

private void send_data(int i)
    {

        textBox2.Text = "";

        int cnt = 0;
        int old_cnt;
        if (i == 1)
        {

            textBox2.Text += textBox1.Lines[cnt];


            Regex Gcode = new Regex("[ngxyzf][+-]?[0-9]*\\.?[0-9]*", RegexOptions.IgnoreCase);
            MatchCollection m = Gcode.Matches(this.textBox2.Text);


            double X, Y, Z, F;


            int g_code = 0;
            int x_code = 0, y_code = 0, z_code = 0, x_int1 = 0, x_int2 = 0, y_int1 = 0, y_int2 = 0, z_int1 = 0, z_int2 = 0;
            float x = 0, y = 0, z = 0, x_float = 0, y_float = 0, z_float = 0;


            foreach (Match n in m)
            {

                if (n.Value.StartsWith("G"))
                {
                    g_code = Convert.ToInt32(ExtractNumbers(n.Value));
                }

                if (n.Value.StartsWith("X"))
                {
                    x = float.Parse(ExtractNumbers(n.Value));
                    x_int1 = (int)x;
                    x_int2 = x_int1;
                    x_float = x - (float)x_int1;
                    x_float = x_float * 1000;
                    x_code = (int)x_float;

                }

                if (n.Value.StartsWith("Y"))
                {
                    y = float.Parse(ExtractNumbers(n.Value));
                    y_int1 = (int)y;
                    y_int2 = y_int1;
                    y_float = y - (float)y_int1;
                    y_float = y_float * 1000;
                    y_code = (int)y;

                }

                if (n.Value.StartsWith("Z"))
                {
                    z = float.Parse(ExtractNumbers(n.Value));
                    z_int1 = (int)z;
                    z_int2 = z_int1;
                    z_float = z - (float)z_int1;
                    z_float = z_float * 1000;
                    z_code = (int)z;


                }


            }

            i = 0;
            //write_data = 0;

           ExchangeInputAndOutputReports(g_code, x_code, y_code, z_code, x_int2, y_int2, z_int2);
            //textBox2.Text = "";
            cnt++;

        }
        //textBox2.Text = "";
        //cnt++;
    }

I am calling this function from following function

public void GetInputReportData( IAsyncResult ar ) 
    {             
        String byteValue = null; 
        Int32 count = 0; 
        Byte[] inputReportBuffer = null; 
        Boolean success = false;
        //int test = 0;
        Int32 write_data = 0;

        try 
        { 
             inputReportBuffer = (byte[])ar.AsyncState; 

            fileStreamDeviceData.EndRead(ar);

            tmrReadTimeout.Stop();

            if ( ( ar.IsCompleted ) ) 
            {
                MyMarshalToForm("AddItemToListBox", "An Input report has been read.");                     
                MyMarshalToForm( "AddItemToListBox", " Input Report ID: " + String.Format( "{0:X2} ", inputReportBuffer[ 0 ] ) );                     
                MyMarshalToForm( "AddItemToListBox", " Input Report Data:" ); 

                for ( count=0; count <= inputReportBuffer.Length -1 ; count++ ) 
                {                         
                    //  Display bytes as 2-character Hex strings.

                    byteValue = String.Format( "{0:X2} ", inputReportBuffer[ count ] ); 

                    MyMarshalToForm( "AddItemToListBox", " " + byteValue ); 
                    MyMarshalToForm( "AddItemToTextBox", byteValue );                         
                }

                //------------------------------------------------------------

                write_data = Convert.ToInt32(inputReportBuffer[1]);
                if (write_data == 1)
                {

                    //lbltest.Text = Convert.ToString(write_data);
                    send_data(1);
                }
                //test = 1;


                                } 
            else 
            { 
                MyMarshalToForm( "AddItemToListBox", "The attempt to read an Input report has failed." ); 
                Debug.Write( "The attempt to read an Input report has failed" );                    
            } 

            MyMarshalToForm( "ScrollToBottomOfListBox", "" ); 

            //  Enable requesting another transfer.

            MyMarshalToForm( "EnableCmdOnce", "" );
            transferInProgress = false;


        } 
        catch ( Exception ex ) 
        { 
            DisplayException( this.Name, ex ); 
            throw ; 
        }             
    } 

When calling the first function I am getting Cross threading not allowed error and I have tried invoke method as well. But I can not do it properly. can someone tell me a solution for this problem

jay_t55
  • 11,362
  • 28
  • 103
  • 174
Sthn
  • 9
  • 2
  • 2
    Your function is running in a different thread than the UI. Changing something in the UI (textBox2.Text in your case) from a different thread is not allowed. Search for `Form.Invoke` you will find many threads for this. – joe Aug 16 '13 at 12:10
  • An awful lot of code but I still can't spot anything relevant. What is `MyMarshalToForm()` and where are you starting anything threaded or async? – H H Aug 16 '13 at 12:17
  • Possible duplicate: http://stackoverflow.com/questions/142003/cross-thread-operation-not-valid-control-accessed-from-a-thread-other-than-the?rq=1 - also, see this link to learn why cross-threading is not allowed: http://stackoverflow.com/questions/2798812/net-controls-why-arent-all-calls-thread-safe – jay_t55 Aug 16 '13 at 12:22
  • A cursory search of just StackOverflow shows *several* answers to this question. – Peter Ritchie Aug 16 '13 at 12:45

2 Answers2

2

Please note that mentions @joe

try this:

        Action action = () => textBox2.Text = "";
        textBox2.Invoke(action);
Mate
  • 4,976
  • 2
  • 32
  • 38
  • What do you think is inside `MyMarshalToForm()` ? – H H Aug 16 '13 at 12:24
  • Hey @Henk Holterman. I'll wait op response to your comment. Thx – Mate Aug 16 '13 at 12:37
  • `MyMarshalToForm()` is calling `send_data` **somehow** and this is where the problem probably lies. Replacing `textBox2.Text = "";` with `send_data` seems pretty obvious, no? – Sinatr Aug 16 '13 at 12:40
0

Or try this (as it seems what send_data is inside the Form already):

BeginInvoke((MethodInvoker)delegate { textBox2.Text = ""; });

BeginInvoke will not update control immediately, but "soon". And I personally prefer that syntax more.

Sinatr
  • 20,892
  • 15
  • 90
  • 319