using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.IO.Ports; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; namespace ProductionControl.Utils { public class SSerialPort { private SerialPort _serialPort; private readonly ConcurrentQueue _messageQueue; private readonly EventWaitHandle _messageWaitHandle; private int _receiveCount, _sendCount; private readonly object _lock; private int queueSize; public int ReceiveCount { get => _receiveCount; } public int SendCount { get => _sendCount; } /// /// /// /// /// /// 队列最大容量 public SSerialPort(string com, int baud,int size=-1) { // initialized _lock = new object(); _receiveCount = 0; _sendCount = 0; _messageQueue = new ConcurrentQueue(); _messageWaitHandle = new EventWaitHandle(false, EventResetMode.AutoReset); queueSize = size; // Open Com openCom(com.ToUpper(), baud); // Receive byte pushMessage(); } private void openCom(string com, int baud) { // Open Com _serialPort = new SerialPort(com, baud); if (_serialPort.IsOpen) _serialPort.Close(); // Set the read / write timeouts _serialPort.ReadTimeout = 500; _serialPort.WriteTimeout = 500; // Set read / write buffer Size,the default of value is 1MB _serialPort.ReadBufferSize = 1024 * 1024; _serialPort.WriteBufferSize = 1024 * 1024; _serialPort.Open(); // Discard Buffer _serialPort.DiscardInBuffer(); _serialPort.DiscardOutBuffer(); } #region Static /// /// 获取当前计算机的串行端口名的数组 /// /// public static string[] getPortNames() { return SerialPort.GetPortNames(); } /// /// 波特率 /// /// public static List getBaudrateList() { return new List() { "300", "600", "1200", "2400", "4800", "9600", "19200", "38400", "57600", "115200", "230400", "460800", "921600" }; } #endregion #region Receive private void pushMessage() { _serialPort.DataReceived += (sender, e) => { lock (_lock) { if (_serialPort.IsOpen == false) return; int length = _serialPort.BytesToRead; byte[] buffer = new byte[length]; int readLen = _serialPort.Read(buffer, 0, length); API.OutputDebugString($"serialPort 缓存中长度:{length},实际读取长度:{readLen}."); if (readLen > 0) { _receiveCount += length; _messageQueue.Enqueue(buffer); byte[] outObj; while (queueSize > 0 && _messageQueue.Count > queueSize) { API.OutputDebugString($"serialPort 删除队列1项,队列中数量:{_messageQueue.Count},队列大小:{queueSize}"); _messageQueue.TryDequeue(out outObj); } _messageWaitHandle.Set(); } } }; } /// /// 获取串口接受到的内容 /// /// 取消息的超时时间 /// 返回byte数组 public byte[] getMessage(int millisecondsToTimeout = -1) { if (_messageQueue.TryDequeue(out var message)) { return message; } if (_messageWaitHandle.WaitOne(millisecondsToTimeout)) { if (_messageQueue.TryDequeue(out message)) { return message; } } return default; } #endregion #region Send /// /// 发送消息(byte数组) /// /// /// /// public void send(byte[] buffer, int offset, int count) { lock (_lock) { _serialPort.Write(buffer, offset, count); //_sendCount += (count - offset); _sendCount += count; } } /// /// 发送消息(字符串) /// /// 字符串编码方式,具体方式见 /// public void send(Encoding encoding, string message) { lock (_lock) { var buffer = encoding.GetBytes(message); _serialPort.Write(buffer, 0, buffer.Length); _sendCount += buffer.Length; } } #endregion /// /// 清空接受/发送总数统计 /// public void clearCount() { lock (_lock) { _sendCount = 0; _receiveCount = 0; } } /// /// 关闭串口 /// public void close() { _serialPort.Close(); } } }