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
{
// 忽略日志异常,保证主流程稳定
}
}
}
}