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()
{
while (await ReceiveChannel.Reader.WaitToReadAsync(TaskCancellationTokenSource.Token))
{
try
{
// 清空列表但保留容量
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
}
}