2017-09-07 12 views
1

私は素晴らしく素晴らしいC#プログラムを持っていますが、シリアル受信バイトの処理は遅すぎます。そして、私はおそらくバックグラウンドワーカーを使ってこの問題を解決できると思っていますが、私はそれを経験しておらず、以前のすべてのアテンプが失敗しました。C#この設定でバックグラウンドを実装するにはどうすればよいですか?

private void serial_DataReceived(object sender, SerialDataReceivedEventArgs e) 
     { 
      rxBuffer += serial.ReadExisting(); // add new bytes to the string 'rxBuffer' 

      this.Invoke(new EventHandler(serialReceived)); 
     } 

     private void serialReceived(object s, EventArgs e) 
     { 
      while (rxBuffer.Length > 0) // keep processing bytes until the string is empty 
      { 
       // textBox1.Text += rxBuffer[0]; 
       byte b = Convert.ToByte(rxBuffer[0]); 
       string hexValue = b.ToString("X"); 

       rxBuffer = rxBuffer.Remove(0, 1); // removes the 'captured' byte from the string 
       ..... 
       lots of code 

このwhileループは、私のプログラム全体の75%です。複雑なバイト
contollのUI要素は、テキストファイルの保存や読み込み、シリアルポート経由のバイト送信を行うことができます。

このシステムは動作しますが、速度が遅すぎます。だから私は、バックグラウンドワーカーでwhileループを動かすことで解決できると思います。

現在のコード設定でバックグラウンドワーカーを実装するにはどうすればよいですか?これまでの私の試みはすべて失敗しました。

編集: 私はちょうど以下にコメントしたものを追加したいと思います。私はserial_DataReceivedが1バイトごとに呼び出されると考えました。私のアプリケーションでは2バイトの受信バイトの間に2msの遅延があります。 ReadExisting()は1バイト以上を返すことがあります。シリアルイベントには何らかの遅延があります。私もQtでこれを持っていましたが、これは決して問題ではありませんでした。私はそれを一度に文字列全体を受け取る機能と考えています。

個人的には、invoke()はすべての処理が遅くなると思っていますが、C#の以前の経験はないので、私はちょうど推測しています。

+0

バックグラウンドワーカーの使い方を教えてくれるリンクです。 https://stackoverflow.com/questions/6481304/how-to-use-a-backgroundworker –

+1

'ReadExisting'を使用する理由は何ですか?特にあなたが本当にバイトに興味があるならば? [SerialPort.Read](https://msdn.microsoft.com/en-us/library/ms143549(v = vs.110).aspx)は、バイトをバッファに直接読み込みます。文字列処理全体が遅いプロセスであるように見えますが、バックグラウンドに置くと速くなりません。既に 'serial_DataReceived'イベントを実装しているので、あなたのプロセスはすでにバックグラウンドスレッドにあります。 –

+0

'たくさんのコード'で 'Invoke'呼び出しが必要なのは何ですか?呼び出しはおそらくそれを遅くしているでしょう(私の以前の仮定は文字列の処理について間違っています)。 –

答えて

0

このコードは解決策であるようです。私は私のGUIは、私はisBusy()フラグを使用してみましたが、それは私が代わりにtryおよびcatchブロックを使用するように動作しませんでしたsignicantlyスムーズに

private void serial_DataReceived(object sender, SerialDataReceivedEventArgs e) 
    { 
     rxBuffer += serial.ReadExisting(); 

     try { backgroundWorker1.RunWorkerAsync(); } catch { } 
    } 


    private void backgroundWorker1_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e) 
    { 
     //private void serialReceived(object s, EventArgs e) 
     //{ 
     while (rxBuffer.Length > 0) 
     { 
      // textBox1.Text += rxBuffer[0]; 
      byte b = Convert.ToByte(rxBuffer[0]); 
      string hexValue = b.ToString("X"); 

      rxBuffer = rxBuffer.Remove(0, 1); 

を実行していることに気づきます。

serial_Datareceivedは文字列rxBufferに新しいバイトを追加し続け、backgroundworkerはrxStringのすべての1バイトが処理されるようにします。

EDIT: 問題がありますが、パネルを除いてUI要素を制御できません。今ちょうど見つけた。私はまだ別のスレッドにいるときにUI要素にアクセスしようとしています。

0

私は多くの人がシリアルポート経由でコマンドを送受信しているところです。私はここでは、コンピュータ/デバイス間の非同期通信を連続的に達成するために、バックグラウンドワーカーとステートマシンを使用することについて語っている素晴らしい例であるhttps://stackoverflow.com/a/38536373/2009197を持っています。別のスレッドでデータを受け取るように、UIスレッドの更新を呼び出す必要があります。

関連する問題