using CapMachine.Wpf.Services; using System; using System.Threading; namespace CapMachine.Wpf.Models { /// /// 监控值日志 /// 负责监控5个整型值的变化。通过5个独立的更新方法实时赋值(建议调用周期≈500ms)。 /// 当值发生变化时,记录“旧值 -> 新值”到日志,仅在变化时记录以保证效率。 /// 线程安全:采用 Interlocked/Volatile 保证无锁原子更新,避免不必要的锁竞争。 /// public class MonitorValueLog { /// /// 日志服务 /// public ILogService LogService { get; } private readonly string _name1; private readonly string _name2; private readonly string _name3; private readonly string _name4; private readonly string _name5; private volatile int _value1; private volatile int _value2; private volatile int _value3; private volatile int _value4; private volatile int _value5; // 0=未初始化,1=已初始化;使用int以便Interlocked操作 private int _v1Initialized; private int _v2Initialized; private int _v3Initialized; private int _v4Initialized; private int _v5Initialized; private readonly string _context; /// /// 构造函数 /// /// 日志服务 public MonitorValueLog(ILogService logService) : this(logService, "Value1", "Value2", "Value3", "Value4", "Value5", null) { } /// /// 构造函数,支持为5个值自定义名称和上下文标识 /// /// 日志服务 /// 值1名称 /// 值2名称 /// 值3名称 /// 值4名称 /// 值5名称 /// 上下文/标签(可选),用于区分不同监控源 public MonitorValueLog(ILogService logService, string name1, string name2, string name3, string name4, string name5, string context = null) { LogService = logService ?? throw new ArgumentNullException(nameof(logService)); _name1 = string.IsNullOrWhiteSpace(name1) ? "Value1" : name1; _name2 = string.IsNullOrWhiteSpace(name2) ? "Value2" : name2; _name3 = string.IsNullOrWhiteSpace(name3) ? "Value3" : name3; _name4 = string.IsNullOrWhiteSpace(name4) ? "Value4" : name4; _name5 = string.IsNullOrWhiteSpace(name5) ? "Value5" : name5; _context = string.IsNullOrWhiteSpace(context) ? string.Empty : $"[{context}] "; } /// /// 当前值的只读访问器(可选) /// public int Value1 => Volatile.Read(ref _value1); public int Value2 => Volatile.Read(ref _value2); public int Value3 => Volatile.Read(ref _value3); public int Value4 => Volatile.Read(ref _value4); public int Value5 => Volatile.Read(ref _value5); /// /// 更新第1个值(仅在变化时记录:旧值 -> 新值) /// /// 新值 public void UpdateValue1(int newValue) => Update(ref _value1, ref _v1Initialized, _name1, newValue); /// /// 更新第2个值(仅在变化时记录:旧值 -> 新值) /// /// 新值 public void UpdateValue2(int newValue) => Update(ref _value2, ref _v2Initialized, _name2, newValue); /// /// 更新第3个值(仅在变化时记录:旧值 -> 新值) /// /// 新值 public void UpdateValue3(int newValue) => Update(ref _value3, ref _v3Initialized, _name3, newValue); /// /// 更新第4个值(仅在变化时记录:旧值 -> 新值) /// /// 新值 public void UpdateValue4(int newValue) => Update(ref _value4, ref _v4Initialized, _name4, newValue); /// /// 更新第5个值(仅在变化时记录:旧值 -> 新值) /// /// 新值 public void UpdateValue5(int newValue) => Update(ref _value5, ref _v5Initialized, _name5, newValue); /// /// 内部更新逻辑:原子更新与变化日志 /// private void Update(ref int target, ref int initializedFlag, string name, int newValue) { // 首次赋值:仅建立基线,不记录日志 if (Interlocked.CompareExchange(ref initializedFlag, 1, 0) == 0) { Volatile.Write(ref target, newValue); return; } // 原子交换拿到旧值 int oldValue = Interlocked.Exchange(ref target, newValue); if (oldValue != newValue) { LogChange(name, oldValue, newValue); } } /// /// 记录变化日志(防御性:日志失败不影响主流程) /// private void LogChange(string name, int oldValue, int newValue) { try { LogService.Info($"{_context}[MonitorValueLog] {name} 变化: {oldValue} -> {newValue}"); } catch { // 忽略日志异常,保证主流程稳定 } } } }