2017-04-13 18 views
-1

这里只是一个小问题,这个代码我成功地从我的串行端口获取数据,但是当我想要在标签中看到这些数据时,我得到了这个: System.InvalidOperationException: '调用线程不能访问这个对象,因为另一个线程是所有者'。 我不确定什么是调度程序以及如何使用它。你能解释给我吗?使用串行端口的线程问题

public void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e) 
    { 
     //init serialport comport 
     SerialPort comport = (SerialPort)sender; 
     // Shortened and error checking removed for brevity... 
     if (!comport.IsOpen) return; 
     int bytes = comport.BytesToRead; 
     byte[] buffer = new byte[bytes]; 
     comport.Read(buffer, 0, bytes); 
     HandleSerialData(buffer, comport); 
    } 

    public void HandleSerialData(byte[] respBuffer, SerialPort comport) 
    { 
     StringBuilder hex = new StringBuilder(respBuffer.Length * 2); 
     foreach (byte b in respBuffer) 
     hex.AppendFormat("{0:x2}", b); 
     string hex2 = hex.ToString(); 
     hex2 = hex2.Substring(22, 8); 
     EnOcean_Label.Dispatcher.CheckAccess(); 
     EnOcean_Label.Content = hex2; 


    }** 
+0

'Dispatcher.BeginInvoke((=){EnOcean_Label.Content = hex2;});'将执行添加到原始线程的调用堆栈。 –

+0

你使用wpf还是表单? –

+0

对于多线程应用程序,UI在另一个线程上执行。您必须通过调度程序(或类似的)调用某些内容来更新UI。 – BurnsBA

回答

1

试试这个。

public void HandleSerialData(byte[] respBuffer, SerialPort comport) 
{ 
    StringBuilder hex = new StringBuilder(respBuffer.Length * 2); 
    foreach (byte b in respBuffer) 
    hex.AppendFormat("{0:x2}", b); 
    string hex2 = hex.ToString(); 
    hex2 = hex2.Substring(22, 8); 
    //EnOcean_Label.Dispatcher.CheckAccess(); 
    Dispatcher.BeginInvoke((Action)(()=>{EnOcean_Label.Content = hex2;})); 

} 
+0

CS1660 C#无法转换lambda表达式键入'委托',因为它不是委托类型//我恐怕不起作用 –

+0

可能需要将其作为“操作”来投放。看我的编辑。 –

+0

它的作品谢谢你的一切 –

0

你必须在UI线程上调用它。

你打电话给EnOcean_Label.Dispatcher.CheckAccess();,但这还不够,因为它只是让你知道它是否与Dispatcher相关的线程。

更好地调用Dispatcher.Invoke这将保证代码将在分派器线程上运行。