176 lines
5.5 KiB
C#
176 lines
5.5 KiB
C#
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;
|
||
|
||
/// <summary>
|
||
/// 扫描仪数据接收事件(外部可订阅,实时获取串口数据)
|
||
/// </summary>
|
||
public event EventHandler<Message> ScannerDataReceived;
|
||
|
||
#region Base
|
||
public override async Task<string> 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<string> 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
|
||
|
||
/// <summary>
|
||
/// 串口DataReceived事件的处理方法(自动触发)
|
||
/// </summary>
|
||
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);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 触发自定义事件(线程安全的事件触发方式)
|
||
/// </summary>
|
||
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<Message> 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<ConnectionState> CheckConnected()
|
||
{
|
||
await Task.Delay(0);
|
||
if (this.MegaSerialPort.IsOpen)
|
||
{
|
||
return ConnectionState.IsConnected;
|
||
}
|
||
else
|
||
{
|
||
return ConnectionState.NotConnected;
|
||
}
|
||
}
|
||
|
||
public override async Task<ConnectionState> ReconnectAsync()
|
||
{
|
||
await Task.Delay(0);
|
||
if (string.IsNullOrEmpty(await ConnectionAsync()))
|
||
{
|
||
return ConnectionState.IsConnected;
|
||
}
|
||
else
|
||
{
|
||
return ConnectionState.NotConnected;
|
||
}
|
||
}
|
||
|
||
}
|
||
}
|