C00225155-02/C00225155/MegaRobo.C00225155/MegaRobo.C00225155.ControlD.../USBScanner/USBScannerService.cs

176 lines
5.5 KiB
C#
Raw Permalink 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 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;
}
}
}
}