1

RS232 を I2C コンバーターにポーリングするアプリを開発しています。これには i2c デバイスが接続されており、リアルタイムでポーリングする必要があります。つまり、常に :D 応答が来たらすぐにコマンドを再発行します...

私のコード:

        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;                    
            }
        }

ここで、ReadFixed は拡張子です。

    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 使用率が発生します。ANTS プロファイラーを使用したところ、関数 READFIXED がホットであり、内部で消費される CPU が非常に高いと表示されます。

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

返信ありがとうございます。

4

1 に答える 1

3

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

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

于 2014-11-02T14:05:11.110 に答える