using System.Diagnostics; namespace RobotNet.RobotManager.Services; public class WatchTimer(int Interval, Action Callback, LoggerController? Logger) : IDisposable where T : class { private System.Threading.Timer? Timer; private readonly Stopwatch Watch = new(); public bool Disposed; private void Handler(object? state) { try { Watch.Restart(); Callback.Invoke(); Watch.Stop(); if (Watch.ElapsedMilliseconds >= Interval || Interval - Watch.ElapsedMilliseconds <= 50) { Timer?.Change(Interval, Timeout.Infinite); } else { Timer?.Change(Interval - Watch.ElapsedMilliseconds, Timeout.Infinite); } } catch (Exception ex) { Logger?.Error($"WatchTimer Error: {ex}"); Timer?.Change(Interval, Timeout.Infinite); } } public void Start() { if (!Disposed) { Timer = new Timer(Handler, null, Timeout.Infinite, Timeout.Infinite); Timer.Change(Interval, 0); } else throw new ObjectDisposedException(nameof(WatchTimer)); } public void Stop() { if (Disposed) return; if (Timer != null) { Timer.Change(Timeout.Infinite, Timeout.Infinite); Timer.Dispose(); Timer = null; } } public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } protected virtual void Dispose(bool disposing) { if (Disposed) return; if (disposing) Stop(); Disposed = true; } ~WatchTimer() { Dispose(false); } }