using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using TeamAAS_VP.Core.PLCs; using TeamAAS_VP.Core.Robots; using TeamAAS_VP.Core.Scanners; using TeamAAS_VP.Interfaces; using TeamAAS_VP.Models; using TeamAAS_VP.Models.Scanner; namespace TeamAAS_VP.Services { public class ScannerService : IScannerService, IDisposable { private readonly IPlcService _plcService; private readonly Dictionary _scannerCollection; private readonly object _sync = new object(); public ScannerService(IPlcService plcService) { _scannerCollection = new Dictionary(); _plcService = plcService; } /// /// 创建扫码枪 /// /// /// /// /// public bool CreateScanner(Guid id, ScannerInfo scannerInfo) { if (scannerInfo == null) throw new ArgumentNullException(nameof(scannerInfo)); var scanner = CreateScannerInstance(scannerInfo); scanner.Id = id; lock (_sync) { if (_scannerCollection.ContainsKey(id)) { var currentScanner = _scannerCollection[id]; try { currentScanner.Dispose(); } catch { // 忽略单个扫码枪 Dispose 异常,继续替换 } } _scannerCollection[id] = scanner; } return true; } /// /// 创建扫码枪 /// /// /// /// public Task CreateScannerAsync(Guid id, ScannerInfo scannerInfo) { return Task.Run(() => { return CreateScanner(id, scannerInfo); }); } public IScanner GetScanner(Guid id) { lock (_sync) { if (_scannerCollection.TryGetValue(id, out var scanner)) { return scanner; } } return null; } public Task GetScannerAsync(Guid id) { return Task.Run(() => { return GetScanner(id); }); } public void UnRegisterScanner(Guid id) { IScanner scanner = null; lock (_sync) { if (_scannerCollection.TryGetValue(id, out scanner)) { _scannerCollection.Remove(id); } } if (scanner != null) { try { scanner.Dispose(); } catch { // 忽略释放异常 } } } public Task UnRegisterScannerAsync(Guid id) { return Task.Run(() => UnRegisterScanner(id)); } /// /// 获取所有扫码枪 /// /// public IReadOnlyCollection GetAllScanners() { lock (_sync) { return _scannerCollection.Values.ToList().AsReadOnly(); } } public Task> GetAllScannersAsync() { return Task.Run(() => { return GetAllScanners(); }); } /// /// 尝试获取扫码枪 /// /// /// /// public bool TryGetScanner(Guid id, out IScanner scanner) { lock (_sync) { return _scannerCollection.TryGetValue(id, out scanner); } } public Task<(bool found, IScanner scanner)> TryGetScannerAsync(Guid id) { return Task.Run(() => { IScanner scanner; bool found; lock (_sync) { found = _scannerCollection.TryGetValue(id, out scanner); } return (found, scanner); }); } /// /// 检查是否存在 /// /// /// public bool ContainsScanner(Guid id) { lock (_sync) { return _scannerCollection.ContainsKey(id); } } public Task ContainsScannerAsync(Guid id) { return Task.Run(() => { return ContainsScanner(id); }); } /// /// 移除扫码枪并释放资源,返回是否成功移除 /// /// /// public bool RemoveScanner(Guid id) { IScanner scanner = null; lock (_sync) { if (_scannerCollection.TryGetValue(id, out scanner)) { _scannerCollection.Remove(id); } } if (scanner != null) { try { scanner.Dispose(); } catch { // 忽略释放异常 } return true; } return false; } public Task RemoveScannerAsync(Guid id) { return Task.Run(() => { return RemoveScanner(id); }); } public IScanner GetScannerByNumber(int scannerNo) { if (TryFindScannerByNumber(scannerNo, out _, out var scanner)) { return scanner; } return null; } public Task GetScannerByNumberAsync(int scannerNo) { return Task.Run(() => { return GetScannerByNumber(scannerNo); }); } public Task UnRegisterScannerByNumberAsync(int scannerNo) { return Task.Run(() => UnRegisterScannerByNumber(scannerNo)); } public void UnRegisterScannerByNumber(int scannerNo) { if (TryFindScannerByNumber(scannerNo, out var id, out var scanner)) { // 复用已有的方法以保持行为一致(线程安全、异常处理) UnRegisterScanner(id); } } /// /// 移除所有扫码枪 /// public void RemoveAllScanners() { //依次移除每个扫码枪,确保资源释放 List scannerIds; lock (_sync) { scannerIds = _scannerCollection.Keys.ToList(); } foreach (var id in scannerIds) { RemoveScanner(id); } } /// /// 初始化所有扫码枪 /// /// /// public (bool IsSucceed, string Message) InitializeAllScanners(ScannerInfo[] scanners) { //清除现有扫码枪集合 RemoveAllScanners(); //根据传入的扫码枪信息数组,依次创建并注册扫码枪实例 foreach (var scannerInfo in scanners) { var scanner = CreateScannerInstance(scannerInfo); lock (_sync) { _scannerCollection[scanner.Id] = scanner; } } bool allConnected = true; StringBuilder errorMessages = new StringBuilder(); //获取所有扫码枪并连接 var allScanners = GetAllScanners(); foreach (var scanner in allScanners) { try { scanner.Connect(); } catch { //忽略单个扫码枪连接异常,继续连接其他扫码枪 } if (!scanner.IsConnected) { allConnected = false; errorMessages.AppendLine($"扫码枪[{scanner.Name}]连接失败。"); } } if (allConnected) { return (true, "所有扫码枪初始化并连接成功。"); } else { return (false, errorMessages.ToString()); } } /// /// 初始化所有扫码枪 (异步) /// /// /// public Task<(bool IsSucceed, string Message)> InitializeAllScannersAsync(ScannerInfo[] scanners) { return Task.Run(() => { return InitializeAllScanners(scanners); }); } // 私有工厂方法,避免重复代码 private IScanner CreateScannerInstance(ScannerInfo scannerInfo) { if (scannerInfo == null) throw new ArgumentNullException(nameof(scannerInfo)); IScanner scanner; if (scannerInfo.ScannerBrand == Enums.ScannerBrand.NLS) { scanner = new NlsScanner(scannerInfo); } else { scanner = new NlsScanner(scannerInfo); } return scanner; } /// /// 更新扫码枪编号 /// /// /// public void UpdateScannerNumber(Guid id, int newNumber) { IScanner scanner; lock (_sync) { if (_scannerCollection.TryGetValue(id, out scanner)) { scanner.ScannerNo = newNumber; } } } // 私有帮助方法:通过扫码枪编号查找字典中的条目(线程安全) private bool TryFindScannerByNumber(int scannerNo, out Guid id, out IScanner scanner) { lock (_sync) { foreach (var kvp in _scannerCollection) { var r = kvp.Value; if (r == null) continue; object rawValue = null; var type = r.GetType(); // 1. 直接在扫码枪对象上查找常见编号属性 var prop = type.GetProperty("ScannerNo") ?? type.GetProperty("ScannerNumber") ?? type.GetProperty("Number") ?? type.GetProperty("No"); if (prop != null) { try { rawValue = prop.GetValue(r); } catch { rawValue = null; } } // 2. 如果未找到,尝试从 RobotInfo / Info 属性中获取编号 if (rawValue == null) { var infoProp = type.GetProperty("ScannerInfo") ?? type.GetProperty("Info"); if (infoProp != null) { try { var infoObj = infoProp.GetValue(r); if (infoObj != null) { var infoType = infoObj.GetType(); var numberProp = infoType.GetProperty("ScannerNo") ?? infoType.GetProperty("ScannerNumber") ?? infoType.GetProperty("Number") ?? infoType.GetProperty("No"); if (numberProp != null) { try { rawValue = numberProp.GetValue(infoObj); } catch { rawValue = null; } } } } catch { // 忽略反射读取错误 rawValue = null; } } } if (rawValue != null) { int parsed; try { if (rawValue is int) parsed = (int)rawValue; else parsed = Convert.ToInt32(rawValue); } catch { // 不能转换则跳过 continue; } if (parsed == scannerNo) { id = kvp.Key; scanner = r; return true; } } } } id = Guid.Empty; scanner = null; return false; } // 实现 IDisposable,释放所有扫码枪并清空集合 public void Dispose() { List scanners; lock (_sync) { scanners = _scannerCollection.Values.ToList(); _scannerCollection.Clear(); } foreach (var r in scanners) { try { r.Dispose(); } catch { // 忽略单个释放异常 } } GC.SuppressFinalize(this); } } }