using MegaRobo.Connections; using MegaRobo.Contract; using MegaRobo.ControlDevices.Abstractions; using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; namespace MegaRobo.C00225155.ControlDevices.USBScanner { public class USBScannerService : ConnectorBase { public SerialPortService MegaSerialPort { get; set; } public bool IsConnected => this.MegaSerialPort?.IsOpen ?? false; /// /// 扫描仪数据接收事件(外部可订阅,实时获取串口数据) /// public event EventHandler ScannerDataReceived; #region Base public override async Task Initialize(ICoreService coreService, params object[] args) { await Task.Delay(0); this.CoreService = coreService; if (args != null && args.Length > 0 && args[0] is string portName) { this.SetConnection(portName); } //else //{ // throw new ArgumentException("初始化失败:未传入有效的串口名称(portName)"); //} return string.Empty; } private void SetConnection(string portName) { // 若已有串口实例,先断开并清理 if (MegaSerialPort != null) { Disconnect(); } this.MegaSerialPort = new SerialPortService(portName); this.Connection(); } public string Connection() { try { if (MegaSerialPort != null && !MegaSerialPort.IsOpen) { this.MegaSerialPort.Open(); // 2. 连接成功后订阅串口DataReceived事件(先取消再订阅,防止重复) MegaSerialPort.DataReceived -= MegaSerialPort_DataReceived; // 取消旧订阅 MegaSerialPort.DataReceived += MegaSerialPort_DataReceived; // 新订阅 } } catch (Exception ex) { return ex.Message; } return this.MegaSerialPort.IsOpen ? null : "连接异常"; } public Task ConnectionAsync() { return Task.Run(this.Connection); } public bool Disconnect() { if (MegaSerialPort != null) { // 3. 断开连接前取消事件订阅(避免内存泄漏) MegaSerialPort.DataReceived -= MegaSerialPort_DataReceived; MegaSerialPort.Dispose(); // 触发SerialPortService的Close和资源释放 } return true; } public void Dispose() { this.Disconnect(); this.MegaSerialPort = null; } #endregion Base /// /// 串口DataReceived事件的处理方法(自动触发) /// private void MegaSerialPort_DataReceived(object sender, Message msg) { if (msg == null || msg.Data == null || msg.Data.Length == 0) return; string receivedData = msg.ReadString(SerialPortDataFormat.Char); // 用串口配置的格式解析 // -------------------------- // 步骤2:对外透传数据(触发自定义事件) // 外部订阅ScannerDataReceived即可实时获取数据 // -------------------------- OnScannerDataReceived(msg); } /// /// 触发自定义事件(线程安全的事件触发方式) /// protected virtual void OnScannerDataReceived(Message msg) { // 临时保存事件引用,避免多线程下事件被注销后为空 var handler = ScannerDataReceived; handler?.Invoke(this, msg); } public string SendAndReceive(string cmd, TimeSpan timeout) { string mReply = string.Empty; EventHandler tempHandler = (sender, msg) => { mReply = msg.ReadString(SerialPortDataFormat.Char); }; try { MegaSerialPort.DataReceived += tempHandler; MegaSerialPort.WriteLine(cmd); Stopwatch stopwatch = Stopwatch.StartNew(); while (string.IsNullOrEmpty(mReply) && stopwatch.Elapsed < timeout) { Thread.Sleep(50); } } finally { MegaSerialPort.DataReceived -= tempHandler; } return mReply; } public override async Task CheckConnected() { await Task.Delay(0); if (this.MegaSerialPort.IsOpen) { return ConnectionState.IsConnected; } else { return ConnectionState.NotConnected; } } public override async Task ReconnectAsync() { await Task.Delay(0); if (string.IsNullOrEmpty(await ConnectionAsync())) { return ConnectionState.IsConnected; } else { return ConnectionState.NotConnected; } } } }