dotnet/runtime

SerialPort ReadBufferSize cant set properly in Ubuntu

Open

#112,643 创建于 2025年2月18日

在 GitHub 查看
 (1 评论) (0 反应) (0 负责人)C# (5,445 fork)batch import
area-System.IO.Portshelp wanted

仓库指标

Star
 (17,886 star)
PR 合并指标
 (平均合并 12天 11小时) (30 天内合并 661 个 PR)

描述

Describe the bug

Hello I am coding a program to control a device like "camera". It works like a call device how long to expose to light,and I wait for the time to check what came back.My code is using System.IO.Ports to do this job and wait for enough time the code properly works on Windows.

However,in Ubuntu even i set a long enough time the buffer (which I read) size never goes well. Whatever serialPort.ReadBufferSize I set still get a maxmimn 4095 length buffer.

And I check Ubuntu system settings about /dev/ttyACM0 has 1Mb cache. So I wondering if this is probrom is about the dotnet runtime.

To Reproduce

My code as follow: Main

using SerialPort serialPort = new(SelectedDevice, 115200, Parity.None, 8, StopBits.One);
serialPort.WriteBufferSize = 8192;
serialPort.ReadBufferSize = 8192;
serialPort.Open();
byte[] buffer = Sender.AcquireSpectra(ExposureTime, AverageTimes);
 int delay = (int)(ExposureTime * AverageTimes * 2);
var response = await SendNReadData(serialPort, buffer, delay, 4106);
if (response.Length == 4106)
 {
        var sp = Receiver.ReadSpectrum(response, 0);
        int[] ins = sp.m_nIntensity;
         SpectraPlotModel = SpectraPlot.OnUpdatedGraph(ins);
}

Serial

private static async Task<byte[]> SendNReadData(SerialPort serialPort, byte[] sendBuffer, int delay, int responseBufferLength)
        {
            serialPort.Write(sendBuffer, 0, sendBuffer.Length);
            int timeout = delay * 5;
            using var cancellationTokenSource = new CancellationTokenSource();
            cancellationTokenSource.CancelAfter(timeout);
            await Task.Delay(delay); //必须保留 在windows下会出现4k分包问题
            byte[] responseBuffer = new byte[responseBufferLength];
            var readTask = serialPort.BaseStream.ReadAsync(responseBuffer, 0, responseBuffer.Length, cancellationTokenSource.Token);
            var completedTask = await Task.WhenAny(readTask, Task.Delay(delay, cancellationTokenSource.Token));
            if (completedTask == readTask)
            {
                int bytesRead = await readTask;
                byte[] dataBuffer = new byte[bytesRead];
                Array.Copy(responseBuffer, dataBuffer, bytesRead);
                return dataBuffer;
            }
            else
            {
                return new byte[4];
            }
        }

Further technical details

SDK Version: 9.0.103 System.IO.Ports.dll 8.0.0.0

贡献者指南