2013-08-16 57 views
0

我在调试代码时不断收到此错误。我是编程新手,我已经尝试了解决类似问题的解决方案,但仍然无法解决问题。跨线程不允许

所引发的异常是:

跨线程操作无效:从不是创建它的线程以外的 线程访问控制“TextBox2中”。

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++; 
    } 

我从下面的函数

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 ; 
     }    
    } 

调用这个函数调用时第一个功能我得到跨线程不允许的错误,我已经试过invoke方法为好。但我做不好。谁能告诉我一个解决方案针对此问题

+2

你的函数运行在与UI不同的线程中。不允许更改UI中的某些内容(在您的案例中为textBox2.Text)。搜索'Form.Invoke'你会发现很多线程。 – joe

+0

很多代码,但我仍然无法找到任何相关的东西。什么是'MyMarshalToForm()',你在哪里启动线程或异步? –

+0

可能的重复:http://stackoverflow.com/questions/142003/cross-thread-operation-not-valid-control-accessed-from-a-thread-other-than-the?rq=1 - 另外,看到这个链接,了解为什么不允许跨线程:http://stackoverflow.com/questions/2798812/net-controls-why-arent-all-calls-thread-safe –

回答

2

请注意,提到@joe

试试这个:

 Action action =() => textBox2.Text = ""; 
     textBox2.Invoke(action); 
+1

我喜欢这个解决方案。 –

+0

你认为在MyMarshalToForm()里面有什么? –

+0

嘿@亨克霍尔特曼。我会等待你的评论的回应。 Thx – Mate

0

或者试试这个(因为它似乎什么send_dataForm已经内):

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

BeginInvoke不会立即更新控件,而是“很快”。我个人更喜欢这种语法。