feat(HistoryProcessor): 添加死区检查功能以优化数据库写入

- 引入 ConcurrentDictionary 作为安全字典来缓存最后写入的数值
- 实现死区检查逻辑,仅当数值变化超过 HistoryDeadband 时才写入数据库
- 添加日志记录,显示因未超过死区值而跳过写入的情况
- 保持原有功能完整性,仅优化不必要的数据库写入操作
This commit is contained in:
2025-10-03 20:13:19 +08:00
parent c1818a0c85
commit 1dbae9c208

View File

@@ -16,6 +16,8 @@ public class HistoryProcessor : IVariableProcessor, IDisposable
private readonly Timer _timer; private readonly Timer _timer;
private readonly IRepositoryManager _repositoryManager; private readonly IRepositoryManager _repositoryManager;
private readonly ILogger<HistoryProcessor> _logger; private readonly ILogger<HistoryProcessor> _logger;
private readonly ConcurrentDictionary<int, double> _lastWrittenValues = new(); // 安全字典,缓存最后写入的数值
public HistoryProcessor(IRepositoryManager repositoryManager, ILogger<HistoryProcessor> logger) public HistoryProcessor(IRepositoryManager repositoryManager, ILogger<HistoryProcessor> logger)
{ {
@@ -37,6 +39,23 @@ public class HistoryProcessor : IVariableProcessor, IDisposable
return; return;
} }
// 检查数值变化是否超过死区值
double currentValue = context.Data.NumericValue;
double historyDeadband = context.Data.HistoryDeadband;
int variableId = context.Data.Id;
// 获取上次写入的值,如果不存在则使用当前值(第一次写入)
if (_lastWrittenValues.TryGetValue(variableId, out double lastWrittenValue))
{
// 如果当前值与上次写入值的差值小于等于死区值,则跳过写入
if (Math.Abs(currentValue - lastWrittenValue) <= historyDeadband)
{
_logger.LogDebug("变量 {VariableName} (ID: {VariableId}) 数值变化未超过死区值 {Deadband},跳过写入",
context.Data.Name, context.Data.Id, historyDeadband);
return;
}
}
// 将 VariableDto 转换为 VariableHistory // 将 VariableDto 转换为 VariableHistory
var historyData = new VariableHistory var historyData = new VariableHistory
{ {
@@ -46,6 +65,9 @@ public class HistoryProcessor : IVariableProcessor, IDisposable
Timestamp = DateTime.Now // 记录当前时间 Timestamp = DateTime.Now // 记录当前时间
}; };
// 更新缓存中的最后写入值
_lastWrittenValues[variableId] = currentValue;
_queue.Enqueue(historyData); _queue.Enqueue(historyData);
_logger.LogDebug("变量 {VariableName} (ID: {VariableId}) 历史数据已入队,队列数量: {QueueCount}", context.Data.Name, context.Data.Id, _queue.Count); _logger.LogDebug("变量 {VariableName} (ID: {VariableId}) 历史数据已入队,队列数量: {QueueCount}", context.Data.Name, context.Data.Id, _queue.Count);