ToomossCan 返回值的监控日志

This commit is contained in:
2025-10-17 16:39:16 +08:00
parent 663defc0ff
commit 080d8e1ffa
4 changed files with 354 additions and 189 deletions

View File

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