首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >.NET core 3.0 System.IO.Ports SerialPort始终占用5-10%的CPU

.NET core 3.0 System.IO.Ports SerialPort始终占用5-10%的CPU
EN

Stack Overflow用户
提问于 2019-02-27 18:44:06
回答 2查看 3.1K关注 0票数 3

当我在RaspberryPi上尝试从Linux的串口(uart)读取数据时,在循环中总是得到5-10%的CPU负载。因为SerialPorts应该是阻塞的,所以这不应该使用那么多的cpu负载,或者我错了?

我试了两个代码:

简单代码

代码语言:javascript
复制
var port = new SerialPort("/dev/ttyUSB0", 57600);
port.Open();
while (true)
{
    if (port.BytesToRead > 0)
    {
    while (port.BytesToRead > 0)
        Console.Write($"{port.ReadByte().ToString("X2")} ");
    Console.WriteLine("");
    }
    Thread.Sleep(100);
}

高级代码

代码语言:javascript
复制
static int blockLimit = 100;
static void Main(string[] args)
{
    var port = new SerialPort("/dev/ttyUSB0", 57600);
    port.Open();
    byte[] buffer = new byte[blockLimit];
    Action kickoffRead = null;
    kickoffRead = delegate
    {
        port.BaseStream.BeginRead(buffer, 0, buffer.Length, delegate (IAsyncResult ar)
        {
        try
        {
            int actualLength = port.BaseStream.EndRead(ar);
            byte[] received = new byte[actualLength];
            Buffer.BlockCopy(buffer, 0, received, 0, actualLength);
            raiseAppSerialDataEvent(received);
        }
        catch (IOException exc)
        {
            handleAppSerialError(exc);
        }
        kickoffRead();
        }, null);
    };
    kickoffRead();

    while (true)
        Thread.Sleep(1000);
}

private static void handleAppSerialError(IOException exc)
{
    throw new NotImplementedException();
}

private static void raiseAppSerialDataEvent(byte[] received)
{
    Console.WriteLine(BitConverter.ToString(received));
}

两者都有相同的结果:两个进程一起使用5%到10%的cpu负载

在运行HypriotOS 1.10.0RaspberryPi 3b+上使用.NET Core 3.0 Preview 2System.IO.Ports 4.6.0-preview-19073.11

EN

回答 2

Stack Overflow用户

发布于 2020-02-03 04:24:26

至于现在(NET Core3.1)的SerialPort实现是非常占用CPU资源的。根据dima117 response here .NET Core - Use System.IO.Ports.SerialPort in visual studio code,我已经将Mono SerialPort移植到Net标准库

我已经将它发布到github:

https://github.com/michaldobrodenka/System.IO.Ports.Mono

有了这个SerialPort实现,我的allwinner h3硬件上的CPU使用率从25%下降到5%

票数 2
EN

Stack Overflow用户

发布于 2021-01-09 00:02:36

我也遇到过同样的问题,并使用Jetbrains的dotTrace进行了一些分析。我得到了以下信息:

代码语言:javascript
复制
7.71%   Poll  •  25,862/25,862 ms  •  Interop+Serial.Poll(SafeHandle, PollEvents, Int32, out PollEvents)
  7.71%   PollEvents  •  System.IO.Ports.SerialStream.PollEvents(Int32, Boolean, Boolean, out Nullable)
    7.71%   IOLoop  •  System.IO.Ports.SerialStream.IOLoop
      7.71%   InnerInvoke  •  System.Threading.Tasks.Task.InnerInvoke
         Thread #8

7procent和我在运行top -d 1时看到的差不多。

看一下被调用的方法,我假设使用了轮询,这不是很有效。特别是如果轮询间隔非常短的话。因此,我查看了GitHub上的dotnet源代码,并注意到间隔被硬编码为1ms(845行)。

代码语言:javascript
复制
Interop.PollEvents events = PollEvents(
    1,
    pollReadEvents: hasPendingReads,
    pollWriteEvents: hasPendingWrites,
    out Interop.ErrorInfo? error);

我会看看我是否可以在GitHub存储库创建一个问题。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54903630

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档