dotnet/runtime

SerialPort ReadBufferSize cant set properly in Ubuntu

Open

#112.643 aperta il 18 feb 2025

Vedi su GitHub
 (1 commento) (0 reazioni) (0 assegnatari)C# (5445 fork)batch import
area-System.IO.Portshelp wanted

Metriche repository

Star
 (17.886 star)
Metriche merge PR
 (Merge medio 12g 11h) (661 PR mergiate in 30 g)

Descrizione

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

Guida contributor