78 lines
1.9 KiB
C#
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);
|
|
}
|
|
}
|