小编典典

跨线程操作无效:控件'textBox1'是从不是在[重复]中创建的线程的线程访问的

c#

我想使用UART将微控制器的温度值发送到C#接口,并在上显示温度Label.Content。这是我的微控制器代码:

while(1) {
   key_scan(); // get value of temp
   if (Usart_Data_Ready())
   {
      while(temperature[i]!=0)
      {
         if(temperature[i]!=' ')
         {
            Usart_Write(temperature[i]);
            Delay_ms(1000);
         }
         i = i + 1;
      }
      i =0;
      Delay_ms(2000);
   }
}

而我的C#代码是:

private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
   txt += serialPort1.ReadExisting().ToString();
   textBox1.Text = txt.ToString();
}

但是出现异常“ 跨线程操作无效:从不是在其上创建线程的线程访问的控件’textBox1’ “请告诉我如何从微控制器获取温度字符串并消除此错误!


阅读 275

收藏
2020-05-19

共1个答案

小编典典

您的serialPort1_DataReceived方法中接收的数据来自UI线程之外的另一个线程上下文,这就是您看到此错误的原因。
若要解决此问题,您将必须使用MSDN文章中介绍的调度程序:
如何:对Windows窗体控件进行线程安全调用

因此,不要直接在serialport1_DataReceived方法中设置text属性,而是使用以下模式:

delegate void SetTextCallback(string text);

private void SetText(string text)
{
  // InvokeRequired required compares the thread ID of the
  // calling thread to the thread ID of the creating thread.
  // If these threads are different, it returns true.
  if (this.textBox1.InvokeRequired)
  { 
    SetTextCallback d = new SetTextCallback(SetText);
    this.Invoke(d, new object[] { text });
  }
  else
  {
    this.textBox1.Text = text;
  }
}

因此,在您的情况下:

private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
  txt += serialPort1.ReadExisting().ToString();
  SetText(txt.ToString());
}
2020-05-19