2012-04-16 3 views
0

RS232をI2Cコンバータにポーリングするアプリケーションを開発しています。これはi2cデバイスが接続されており、リアルタイムでポーリングする必要があります。応答は、私は再度コマンドを再発行してくるよう...Monoまたは.NET Serialport頻繁な読み取りの結果が高いCPU

私のコード:

ReadFixedが拡張したものです
 lock (_locker) 
     { 
      try 
      { 

       _serialPort.DiscardInBuffer(); 
       _serialPort.Write(sendArray, 0, sendArray.Length); 
       _serialPort.ReadFixed(headerArray, headerArray.Length); 
       returnOperation = (DeviceOperation)((int)headerArray[1] << 8 | (int)headerArray[3]); 
       DataToReceive = headerArray[5] * 256 + headerArray[6]; 
       if (DataToReceive != 0) 
       { 
        _serialPort.ReadFixed(recvArray, DataToReceive); 
       } 
       _serialPort.ReadFixed(EOT, 1); //EOT 
      } 
      catch (Exception e) 
      { 
       Logger.Log(Level.Error, _name, "Fauled to execute command.", e); 
       return false;      
      } 
     } 

public static void ReadFixed(this SerialPort port, byte[] buffer, int count) 
    { 
     int offset = 0; 
     while (count != offset) 
      offset += port.Read(buffer, offset, count - offset); 

     if (count != offset) 
      throw new TimeoutException("ReadFixed did not receive specified bytes in time!"); 
    } 

コード結果のこの作品約40に - 60%のCPU使用するeをデュアルコアプロセッサで実行します。私はANTSプロファイラを使用し、READFIXED関数が暑く、内部で消費されたCPUが本当に高いと言います。

何が悪いと思いますか?なぜそのようなCPUの使用ですか?私は何か間違っているのですか?

あなたの返信ありがとうございます!

+1

小さな「Thread.Sleep」を追加します。 CPUの使用量が少なくなり、シリアルパフォーマンスが大幅に低下することはありません。 – jgauffin

+1

これは、SerialPortにDataReceivedイベントがある理由です。だからあなたは投票する必要はありません。 –

+0

DataReceivedはモノ/ Linuxでは動作しません...なぜpoll。私も5ミリ秒の睡眠を入れてみましたが、CPU負荷は20-35%に落ちました... C++では高頻度のシリアル通話でCPUの問題があるのを覚えていません – Lonko

答えて

1

デフォルトでは、serialport.Read()は、バイトが受信されたかどうかに関係なく、すぐに戻ります。 serialport.Timeout = 2000を設定すると、バイトが使用可能になるか、2秒後にタイムアウトするまでスレッドはブロックされます。これにより、CPU使用率が低くなり、Thread.Sleepよりも応答性が向上します。

スレッドをブロックすることに注意してください。これが問題の場合は、すべてBackgroundWorkerスレッドで読んでください。たとえば、AutoResetEventを使用してシグナリングを使用して、効率的にフォアグラウンドスレッドと通信することができます。

関連する問題