【问题标题】:Mono or .NET Serialport frequent reads result in high cpuMono 或 .NET Serialport 频繁读取导致高 CPU
【发布时间】:2014-11-02 22:05:11
【问题描述】:

我正在开发一个轮询 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 profiler,它说函数READFIXED很热,里面消耗的cpu真的很高。

知道有什么问题吗?为什么这样的cpu使用率?我是不是做错了什么?

感谢您的回复!

【问题讨论】:

  • 添加一个小的Thread.Sleep。它将使用更少的 CPU,并且不会对串行性能造成太大影响。
  • 这就是 SerialPort 有 DataReceived 事件的原因。所以你不必投票。
  • DataReceived 在单声道/Linux 中不起作用...这就是轮询的原因。我还尝试过 5 毫秒睡眠,cpu 负载下降到 20-35%...在 C++ 上,我不记得在频繁串行调用时遇到 cpu 问题
  • @Lonko - C++ 在某些事情上更有效,这就是使用它的原因。正如已经指出的尝试 DataRecieved 查看 CPU 使用率是否下降。如果你真的想要,你也可以使用 C++ 轮询串口。
  • @Ramhound 不能使用 Datareceived 事件处理程序,因为它没有在 mono/linux 中实现;)否则我会:P

标签: c# mono serial-port cpu


【解决方案1】:

默认情况下serialport.Read() 将立即返回,无论是否接收到字节。如果设置serialport.Timeout = 2000,线程将阻塞,直到字节可用或在 2 秒后超时。这将导致 CPU 使用率降低,并提供比 Thread.Sleep 更好的响应。

请注意,这会阻塞您的线程。如果这是一个问题,请在BackgroundWorker 线程中阅读所有内容。您可以使用信号,例如使用AutoResetEvent,来有效地与前台线程通信。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-10-23
    • 2010-11-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多