Files
ACP/DeviceCommand/Flexible/FSerialPort.cs
2026-07-29 13:12:27 +08:00

105 lines
3.6 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using Common.Attributes;
using System;
using System.IO.Ports;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace DeviceCommand.Flexible
{
[ACPCommand]
public static class FSerialPort
{
private static readonly SemaphoreSlim _commLock = new(1, 1);
private static SerialPort CreatePort(string portName, int baudRate, Parity parity, int dataBits, StopBits stopBits, int sendTimeout,int receiveTimeout)
{
return new SerialPort(portName, baudRate, parity, dataBits, stopBits)
{
Encoding = Encoding.UTF8,
WriteTimeout = sendTimeout > 0 ? sendTimeout : SerialPort.InfiniteTimeout,
ReadTimeout = receiveTimeout > 0 ? receiveTimeout : SerialPort.InfiniteTimeout
};
}
#region
public static async Task SendAsync(string portName,int baudRate,Parity parity,int dataBits,StopBits stopBits,int sendTimeout,int receiveTimeout,string command,CancellationToken ct = default)
{
await _commLock.WaitAsync(ct);
try
{
using var port = CreatePort(
portName, baudRate, parity, dataBits, stopBits, sendTimeout, receiveTimeout);
port.Open();
using var cts = CancellationTokenSource.CreateLinkedTokenSource(ct);
if (sendTimeout > 0)
cts.CancelAfter(sendTimeout);
var bytes = port.Encoding.GetBytes(command);
await port.BaseStream.WriteAsync(bytes, 0, bytes.Length, cts.Token);
await port.BaseStream.FlushAsync(cts.Token);
}
finally
{
_commLock.Release();
}
}
#endregion
#region
public static async Task<string> SendReadAsync(string portName,int baudRate, Parity parity, int dataBits, StopBits stopBits,int sendTimeout, int receiveTimeout,string command,string delimiter = "\n", CancellationToken ct = default)
{
await _commLock.WaitAsync(ct);
try
{
using var port = CreatePort(
portName, baudRate, parity, dataBits, stopBits, sendTimeout, receiveTimeout);
port.Open();
// Send
var sendBytes = port.Encoding.GetBytes(command);
await port.BaseStream.WriteAsync(sendBytes, 0, sendBytes.Length, ct);
await port.BaseStream.FlushAsync(ct);
// Read
delimiter ??= "\n";
var sb = new StringBuilder();
byte[] buffer = new byte[256];
using var cts = CancellationTokenSource.CreateLinkedTokenSource(ct);
if (receiveTimeout > 0)
cts.CancelAfter(receiveTimeout);
while (!cts.Token.IsCancellationRequested)
{
int read = await port.BaseStream.ReadAsync(
buffer, 0, buffer.Length, cts.Token);
if (read == 0)
break;
sb.Append(port.Encoding.GetString(buffer, 0, read));
int index = sb.ToString().IndexOf(delimiter, StringComparison.Ordinal);
if (index >= 0)
return sb.ToString(0, index).Trim();
}
throw new TimeoutException("串口读取超时");
}
finally
{
_commLock.Release();
}
}
#endregion
}
}