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