2017-04-13 41 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這將保證代碼將在分派器線程上運行。