feat: 增加串口异步流操作选项

This commit is contained in:
Diego
2025-06-10 18:00:09 +08:00
parent ac5f8d8610
commit 072c737acc
3 changed files with 61 additions and 5 deletions

View File

@@ -53,6 +53,11 @@ public class SerialPortOption
///<inheritdoc cref = "SerialPort.RtsEnable" />
public bool RtsEnable { get; set; }
/// <summary>
/// 流异步操作
/// </summary>
public bool StearmAsync { get; set; }
/// <inheritdoc/>
public override string ToString()
{

View File

@@ -44,7 +44,7 @@ internal class SerialCore : DisposableObject, IValueTaskSource<SerialOperationRe
/// <summary>
/// Serial核心
/// </summary>
public SerialCore(string portName, int baudRate, Parity parity, int dataBits, StopBits stopBits)
public SerialCore(string portName, int baudRate, Parity parity, int dataBits, StopBits stopBits, bool streamAsync)
{
this.m_receiveCounter = new ValueCounter
{
@@ -59,11 +59,22 @@ internal class SerialCore : DisposableObject, IValueTaskSource<SerialOperationRe
};
this.m_serialPort = new SerialPort(portName, baudRate, parity, dataBits, stopBits);
this.m_serialPort.DataReceived += this.SerialCore_DataReceived;
if (streamAsync)
{
_ = Task.Run(this.BeginReceive);
}
else
{
this.m_serialPort.DataReceived += this.SerialCore_DataReceived;
}
this.m_cancellationToken = this.m_cancellationTokenSource.Token;
}
/// <summary>
/// 最大缓存尺寸
/// </summary>
@@ -130,7 +141,7 @@ internal class SerialCore : DisposableObject, IValueTaskSource<SerialOperationRe
try
{
var segment = memory.GetArray();
this.m_serialPort.Write(segment.Array, segment.Offset, segment.Count);
await this.m_serialPort.BaseStream.WriteAsync(segment.Array, segment.Offset, segment.Count).ConfigureAwait(EasyTask.ContinueOnCapturedContext);
this.m_sendCounter.Increment(memory.Length);
}
@@ -157,6 +168,8 @@ internal class SerialCore : DisposableObject, IValueTaskSource<SerialOperationRe
this.m_serialPort.Close();
this.m_serialPort.Dispose();
this.m_core.SetException(new ObjectDisposedException(nameof(SerialCore)));
}
catch
{
@@ -205,7 +218,45 @@ internal class SerialCore : DisposableObject, IValueTaskSource<SerialOperationRe
// 设置任务源的异常
this.m_core.SetException(ex);
}
}
private async Task BeginReceive()
{
if (this.m_cancellationToken.IsCancellationRequested)
{
return;
}
while (!m_cancellationToken.IsCancellationRequested)
{
try
{
await this.m_receiveLock.WaitAsync(this.m_cancellationToken).ConfigureAwait(EasyTask.ContinueOnCapturedContext);
var bytes = this.m_byteBlock.TotalMemory.GetArray();
var r = await this.m_serialPort.BaseStream.ReadAsync(bytes.Array, 0, this.m_byteBlock.Capacity, m_cancellationToken).ConfigureAwait(false);
if (m_serialPort.BytesToRead > 0)
r += await this.m_serialPort.BaseStream.ReadAsync(bytes.Array, r, this.m_byteBlock.Capacity - r, m_cancellationToken).ConfigureFalseAwait();
this.m_receiveCounter.Increment(r);
var serialOperationResult = new SerialOperationResult(r, SerialData.Chars);
this.m_core.SetResult(serialOperationResult);
}
catch (Exception ex)
{
// 设置任务源的异常
this.m_core.SetException(ex);
}
}
}
private void SetBuffer(ByteBlock byteBlock)

View File

@@ -330,7 +330,7 @@ public abstract class SerialPortClientBase : SetupConfigObject, ISerialPortSessi
private static SerialCore CreateSerial(SerialPortOption option)
{
var serialPort = new SerialCore(option.PortName, option.BaudRate, option.Parity, option.DataBits, option.StopBits);
var serialPort = new SerialCore(option.PortName, option.BaudRate, option.Parity, option.DataBits, option.StopBits, option.StearmAsync);
serialPort.SerialPort.Handshake = option.Handshake;
serialPort.SerialPort.RtsEnable = option.RtsEnable;
serialPort.SerialPort.DtrEnable = option.DtrEnable;