using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Timers;
namespace SKMC.Api.Common.Monitor
{
///
/// 状态锁存管理器, 用于低频的状态判断并锁定
/// 例如总线连接状态、设备物料状态、是否长时间无人操作等
///
public class StateLatchManager : IDisposable
{
private readonly Dictionary _tasks = new Dictionary();
private readonly Timer _timer;
///
/// 监测并锁定的状态
///
private static readonly int LATCH_VAL = -1;
public StateLatchManager(int interval = 5000)
{
_timer = new Timer(interval);
_timer.Elapsed += (s, e) => RunAllTasks();
// 没有限制重入
_timer.AutoReset = true;
}
///
/// 添加任务,支持返回 bool 或可转换为 int 的数值类型
///
public void AddTask(string key, Func task, Action callback = null, LatchMode mode = LatchMode.OpenMode)
{
_tasks[key] = new LatchTask
{
Task = task,
Callback = callback,
Mode = mode
};
}
///
/// 获取任务信息
///
///
///
public LatchTask GetTask(string key)
{
return _tasks.ContainsKey(key) ? _tasks[key] : null;
}
///
/// 获取累计结果
///
public int GetResult(string key)
{
// TODO 如果获取结果的时间戳与当前时间戳差距较大则无效
return _tasks.ContainsKey(key) ? _tasks[key].LatchResult : 0;
}
///
/// 重置任务结果
///
public void ResetResult(string key)
{
if (_tasks.ContainsKey(key))
{
_tasks[key].LatchResult = 0;
_tasks[key].ErrorInfo = null;
_tasks[key].Initialized = false;
}
}
public void Start() => _timer.Start();
public void Stop() => _timer.Stop();
private void RunAllTasks()
{
foreach (var task in _tasks)
{
if (task.Value.LatchResult != LATCH_VAL && task.Value.ErrorInfo == null)
{
try
{
var rawResult = task.Value.Task.DynamicInvoke();
int result = ConvertToInt(rawResult);
if (task.Value.Mode == LatchMode.CloseMode)
{
if (task.Value.Initialized)
{
task.Value.LatchResult &= result;
task.Value.LatchResult = task.Value.LatchResult == 0 ? -1 : 1;
}
else
{
task.Value.LatchResult = result == 0 ? -1 : 1;
task.Value.Initialized = true;
}
}
else if (task.Value.Mode == LatchMode.OpenMode)
{
if (task.Value.Initialized)
{
task.Value.LatchResult &= result;
task.Value.LatchResult = task.Value.LatchResult == 0 ? 1 : -1;
}
else
{
task.Value.LatchResult = result == 0 ? 1 : -1;
task.Value.Initialized = true;
}
}
if (task.Value.LatchResult == LATCH_VAL)
{
task.Value.LatchTime = DateTime.Now;
task.Value.Callback?.Invoke();
}
}
catch(Exception e)
{
task.Value.ErrorInfo = $"ErrorInfo: {e.Message}, Datetime: {DateTime.Now}";
}
}
}
}
private int ConvertToInt(object value)
{
if (value is bool b)
return b ? 1 : 0;
return Convert.ToInt32(value);
}
public void Dispose() => _timer?.Dispose();
}
public class LatchTask
{
///
/// 监测任务
///
public Delegate Task { get; set; }
///
/// 是否已初始化
///
public bool Initialized { get; set; }
///
/// 当前结果
///
public int LatchResult { get; set; }
///
/// 锁存模式
///
public LatchMode Mode { get; set; }
///
/// 触发时间
///
public DateTime LatchTime { get; set; }
///
/// 异常信息
///
public string ErrorInfo { get; set; }
///
/// 触发后回调动作
///
public Action Callback { get; set; }
}
public enum LatchMode
{
///
/// 适用常闭模式:11101/11001返回-1,11111返回1
///
CloseMode,
///
/// 适用常开模式:00010/00110返回-1,00000返回1
///
OpenMode
}
}