Lonko
Lonko

Reputation: 379

Mono or .NET Serialport frequent reads result in high cpu

I'm developing an app that polls RS232 to I2C converter, to which i have an i2c device connected, that has to be polled in realtime, meaning constantly :D As soon as response comes i reissue the command again...

my code:

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

where ReadFixed is an extension:

    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!");
    }

This piece of code results in around 40 - 60 % CPU usage on a dual core processor. I used ANTS profiler and it says that the function READFIXED is hot, and the cpu consumed inside is really high.

Any idea what is wrong? why such cpu usage ? Am I doing something wrong ?

Thank you for your replies!

Upvotes: 1

Views: 1569

Answers (1)

user3279361
user3279361

Reputation: 41

By default serialport.Read() will immediately return, regardless if bytes have been received or not. If you setserialport.Timeout = 2000, the thread will block until bytes are available or it times out after 2 s. This will result in low CPU usage, and will give better responsiveness than a Thread.Sleep.

Be aware that this will block your thread. If this is an issue, do all your reading in a BackgroundWorker thread. You can use signalling, for example by using AutoResetEvent, to efficiently communicate with your foreground thread.

Upvotes: 3

Related Questions