RobotApp/RobotApp/Services/WatchTimer.cs
Đăng Nguyễn d6fe1d9d52 update
2025-09-26 08:48:50 +07:00

78 lines
1.9 KiB
C#

using System.Diagnostics;
namespace RobotApp.Services;
public class WatchTimer<T>(int Interval, Action Callback, Logger<T>? Logger) : IDisposable where T : class
{
private 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)
{
if(Watch.ElapsedMilliseconds > Interval) Logger?.Warning($"WatchTimer Warning: Elapsed time {Watch.ElapsedMilliseconds}ms exceeds interval {Interval}ms.");
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<T>));
}
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);
}
}