2017-04-13 17 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#ラムダ式を変換できませんデリゲート型ではないので、 'Delegate'と打つことができます。//うまくいきません。 –

+0

おそらく 'Action'としてキャストする必要があります。私の編集を参照してください。 –

+0

すべてに感謝します –

0

UIスレッドで呼び出す必要があります。

あなたはEnOcean_Label.Dispatcher.CheckAccess();に電話していますが、ディスパッチャに関連付けられているスレッドかどうかを知らせるだけでは不十分です。

Dispatcher.Invokeを呼び出すと、コードがDispatcherスレッド上で実行されることが保証されます。

関連する問題