LIN CAN 的更改

This commit is contained in:
2025-10-15 16:51:15 +08:00
parent fb4bc6d9d7
commit 087b6e9eff
3 changed files with 237 additions and 114 deletions

View File

@@ -1,4 +1,4 @@
using Prism.Mvvm;
using Prism.Mvvm;
using System;
using System.Collections.Generic;
using System.Linq;
@@ -47,8 +47,18 @@ namespace CapMachine.Wpf.CanDrive
private string? _SignalRtValue = "--";
/// <summary>
/// 信号实时值
/// 信号实时值(供 UI 绑定显示)。
/// </summary>
/// <remarks>
/// - 仅当文本发生变化时才触发通知,避免无谓 UI 刷新。
/// - 若期望进一步降低分配开销,建议在调用方(接收循环)先做“数值层去重”,
/// 即:仅在数值变化(可设置容差)时才调用 ToString() 格式化并赋值到本属性。
/// 这样可以显著减少字符串分配与 GC 压力。
/// </remarks>
/// <example>
/// // 示例:数值层去重后再格式化(接收循环中使用)
/// // if (Math.Abs(newVal - lastVal) > 1e-3) { model.SignalRtValue = newVal.ToString("F3"); lastVal = newVal; }
/// </example>
public string? SignalRtValue
{
get { return _SignalRtValue; }
@@ -62,21 +72,56 @@ namespace CapMachine.Wpf.CanDrive
}
}
private StringBuilder _SignalRtValueSb = new StringBuilder(10);
private StringBuilder _SignalRtValueSb = new StringBuilder(16);
/// <summary>
/// 信号实时值 StringBuilder
/// 信号实时值的可变文本缓冲接口。
/// 设计目的:
/// - 避免外部传入的 StringBuilder 被直接保存(引用别名问题),统一复制文本到内部缓冲 _SignalRtValueSb
/// - 仅当文本内容变化时才更新 SignalRtValue 并 RaisePropertyChanged减少 UI 抖动与无谓刷新;
/// - 对 value == null 做防御:清空内部缓冲并置空显示文本(如需显示 “--” 可按需替换)。
/// 使用方式:
/// - 接收环路可重复复用同一个外部 StringBuilder 作为临时缓存,调用本属性进行更新不会产生实例共享风险。
/// </summary>
/// <remarks>
/// 注意事项:
/// 1) 本属性会复制文本,不会保存外部 StringBuilder 引用;这可避免多个模型共享同一实例导致的数据串扰和并发问题。
/// 2) 若你的 UI 需要统一的“空值占位符”,可将 setter 中的空字符串替换为 "--",与字段初始值保持一致。
/// 3) 线程模型:建议仍在 UI 线程更新以避免跨线程通知问题如需后台线程更新请确保有合适的调度Dispatcher/同步上下文)。
/// 4) 性能建议:结合 SignalRtValue 的备注,在进入本 setter 前尽量做数值层去重,进一步减少字符串分配。
/// </remarks>
/// <example>
/// // 示例:接收循环中复用临时缓存
/// // var tmp = new StringBuilder(32);
/// // ... 填充 tmp ...
/// // model.SignalRtValueSb = tmp; // 本属性会复制 tmp 的内容,安全且不会产生实例共享
/// </example>
public StringBuilder SignalRtValueSb
{
get { return _SignalRtValueSb; }
set
{
//if (_SignalRtValueSb != value)
//{
SignalRtValue = value.ToString();
_SignalRtValueSb = value;
//}
// 防御:若外部传入 null清空内部状态并复位显示文本
// 注意:此处将显示文本设为空字符串 "",如果希望与初始占位符 "--" 一致,可改为 SignalRtValue = "--"。
if (value == null)
{
if (_SignalRtValue != string.Empty)
{
_SignalRtValueSb.Clear();
SignalRtValue = string.Empty;
}
return;
}
// 复制策略:不保存外部 StringBuilder 的引用,改为复制其当前文本内容
// 这样可避免多个模型共享同一 StringBuilder 实例导致的数据串扰与线程安全问题
var str = value.ToString();
// 仅当文本内容确实发生变化时,才更新内部缓冲与绑定属性,减少无谓的 UI 刷新与字符串分配
if (!string.Equals(_SignalRtValue, str, StringComparison.Ordinal))
{
_SignalRtValueSb.Clear();
_SignalRtValueSb.Append(str);
SignalRtValue = str;
}
}
}