using CapMachine.Wpf.CanDrive; using CapMachine.Wpf.Models.HighSpeed; using Prism.Ioc; using Prism.Mvvm; using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Linq; using System.Text; using System.Threading.Channels; using System.Threading.Tasks; using System.Windows.Threading; namespace CapMachine.Wpf.Services { /// /// 高速驱动消息服务 /// 负载高速的驱动数据的消息和转发 /// public class HightDriveMsgService : BindableBase { #region 字段和属性 private readonly ILogService LogService; /// /// 接收数据Channel /// private readonly Channel ReceiveChannel; /// /// 转发数据Channel /// private readonly Channel ForwardChannel; /// /// 取消令牌 /// private CancellationTokenSource TaskCancellationTokenSource; /// /// 数据接受处理任务 /// private Task ProcessTask; /// /// 数据转发处理任务 /// private Task ForwardTask; /// /// 显示的消息集合 /// public ObservableCollection DisplayMessages { get; set; } = new ObservableCollection(); /// /// 最大显示消息数量 /// public int MaxDisplayCount { get; set; } = 200; /// /// 是否启用CAN报文显示 /// private bool _IsDisplayEnabled=true; public bool IsDisplayEnabled { get { return _IsDisplayEnabled; } set { SetProperty(ref _IsDisplayEnabled, value); if (!value) { // 不显示时清空数据节省内存 App.Current.Dispatcher.Invoke(() => DisplayMessages.Clear()); } } } /// /// 是否启用CAN数据转发 /// private bool _IsForwardEnabled; public bool IsForwardEnabled { get { return _IsForwardEnabled; } set { SetProperty(ref _IsForwardEnabled, value); } } #endregion #region 构造和初始化 /// /// 构造函数 /// /// 容器服务提供者 /// 日志服务 public HightDriveMsgService(ILogService logService) { LogService = logService; // 创建接收Channel,设置容量和溢出策略 ReceiveChannel = Channel.CreateBounded(new BoundedChannelOptions(100000) { FullMode = BoundedChannelFullMode.DropOldest, // 满时删除旧数据 SingleReader = true, // 单一读取者 SingleWriter = false // 允许多个写入者 }); // 创建转发Channel ForwardChannel = Channel.CreateBounded(new BoundedChannelOptions(100000) { FullMode = BoundedChannelFullMode.DropOldest, SingleReader = true, SingleWriter = false }); // 初始化服务 Initialize(); } /// /// 初始化服务 /// private void Initialize() { TaskCancellationTokenSource = new CancellationTokenSource(); // 启动数据处理任务 ProcessTask = Task.Run(ProcessMessagesAsync); // 启动数据转发任务 ForwardTask = Task.Run(ForwardMessagesAsync); //LogService.Info("HightDriveMsgService初始化完成"); } #endregion #region 公共方法 /// /// 添加CAN消息进行处理 /// /// CAN消息 /// 是否添加成功 public async Task AddMessageAsync(CommMsg message) { if (message == null) return false; try { if (IsDisplayEnabled) { // 添加到接收Channel await ReceiveChannel.Writer.WriteAsync(message, TaskCancellationTokenSource.Token); } // 如果启用转发,也添加到转发Channel 需要判断目标的CAN是否已经打开,如果打开的话,则转发数据 if (IsForwardEnabled) { await ForwardChannel.Writer.WriteAsync(message, TaskCancellationTokenSource.Token); } return true; } catch (OperationCanceledException) { return false; } catch (Exception ex) { LogService.Error($"添加CAN消息失败: {ex.Message}"); return false; } } /// /// 批量添加CAN消息 /// /// 消息集合 /// 成功添加的消息数量 public async Task AddMessagesAsync(IEnumerable messages) { if (messages == null) return 0; int successCount = 0; foreach (var message in messages) { if (await AddMessageAsync(message)) { successCount++; } } return successCount; } /// /// 设置转发目标CAN设备 /// /// 目标设备 public void SetForwardTarget(ToomossCan targetDevice) { //_targetCanDevice = targetDevice; LogService.Info($"设置转发目标设备: {(targetDevice != null ? "成功" : "未设置")}"); } /// /// 清空显示消息 /// public void ClearDisplayMessages() { App.Current.Dispatcher.Invoke(() => DisplayMessages.Clear()); } #endregion #region 私有方法 /// /// 批量处理消息提高效率 /// private List MessageBatch { get; set; } = new List(); /// /// 接受的批次数量 /// private int ReciveBatchCount { get; set; } /// /// 转发的批次数量 /// private int ForwardBatchCount { get; set; } /// /// 异步处理接收到的消息 /// private async Task ProcessMessagesAsync() { try { while (await ReceiveChannel.Reader.WaitToReadAsync(TaskCancellationTokenSource.Token)) { // 清空列表但保留容量 MessageBatch.Clear(); // 读取最多100条消息或直到没有更多消息 ReciveBatchCount = 0; while (ReciveBatchCount < 30 && ReceiveChannel.Reader.TryRead(out CommMsg message)) { MessageBatch.Add(message); ReciveBatchCount++; } if (MessageBatch.Count > 0 && IsDisplayEnabled) { // 在UI线程更新显示 await App.Current.Dispatcher.InvokeAsync(() => { foreach (var msg in MessageBatch) { DisplayMessages.Add(msg); // 控制显示消息数量 while (DisplayMessages.Count > MaxDisplayCount) { DisplayMessages.RemoveAt(0); } } }, DispatcherPriority.Background); } // 避免CPU过度使用 if (ReciveBatchCount == 0) { await Task.Delay(20); } } } catch (OperationCanceledException ex) { // 服务被取消,正常退出 LogService.Error($" 服务被取消,正常退出: {ex.Message}"); } catch (Exception ex) { LogService.Error($"消息处理任务异常: {ex.Message}"); } } /// /// 异步转发消息 /// private async Task ForwardMessagesAsync() { try { while (await ForwardChannel.Reader.WaitToReadAsync(TaskCancellationTokenSource.Token)) { //// 只有在启用转发且目标设备可用时才处理 && _targetCanDevice != null && _targetCanDevice.OpenState //if (IsForwardEnabled) //{ // // 批量收集转发消息 // List canMessages = new List(); // ForwardBatchCount = 0; // // 一次最多处理50条消息 // while (ForwardBatchCount < 50 && ForwardChannel.Reader.TryRead(out CommMsg message)) // { // if (message.Category == "CAN" && !string.IsNullOrEmpty(message.MsgInfo)) // { // try // { // // 转换为CAN_MSG格式 // USB2CAN.CAN_MSG canMsg = new USB2CAN.CAN_MSG(); // canMsg.Data = new byte[64]; // // 解析CAN ID // string msgIdHex = message.MsgInfo.Replace("0x", ""); // canMsg.ID = Convert.ToUInt32(msgIdHex, 16); // // 解析数据 // string[] dataBytes = message.MsgData.Split('-'); // canMsg.DataLen = (byte)dataBytes.Length; // for (int i = 0; i < dataBytes.Length && i < 64; i++) // { // canMsg.Data[i] = Convert.ToByte(dataBytes[i], 16); // } // canMessages.Add(canMsg); // } // catch (Exception ex) // { // LogService.Error($"转换CAN消息格式失败: {ex.Message}"); // } // } // ForwardBatchCount++; // } // // 批量发送转发消息 // if (canMessages.Count > 0) // { // //// 在这里调用设备API发送消息 // //int sendResult = USB2CAN.CAN_SendMsg( // // _targetCanDevice.DevHandle, // // _targetCanDevice.WriteCANIndex, // // canMessages.ToArray(), // // (uint)canMessages.Count); // //if (sendResult < 0) // //{ // // LogService.Error($"CAN消息转发失败: 错误码={sendResult}"); // //} // //else // //{ // // LogService.Debug($"成功转发{sendResult}条CAN消息"); // //} // } //} //else //{ // // 不转发时,清空队列减少内存占用 // while (ForwardChannel.Reader.TryRead(out _)) { } // await Task.Delay(10); //} } } catch (OperationCanceledException) { // 服务被取消,正常退出 } catch (Exception ex) { LogService.Error($"消息转发任务异常: {ex.Message}"); } } #endregion #region IDisposable 实现 /// /// 释放资源 /// public void Dispose() { try { // 发送取消信号 TaskCancellationTokenSource?.Cancel(); // 等待任务完成 Task.WaitAll(new[] { ProcessTask, ForwardTask }, 1000); } catch { /* 忽略取消异常 */ } finally { // 释放资源 TaskCancellationTokenSource?.Dispose(); TaskCancellationTokenSource = null; // 完成写入器,表示不再接受新数据 ReceiveChannel.Writer.Complete(); ForwardChannel.Writer.Complete(); // 清空显示数据 App.Current.Dispatcher.Invoke(() => DisplayMessages.Clear()); LogService.Info("HightDriveMsgService资源已释放"); } } #endregion } }