RobotNet/RobotNet.RobotManager/Services/WatchTimerAsync.cs
2025-10-15 15:15:53 +07:00

77 lines
1.8 KiB
C#

using System.Diagnostics;
namespace RobotNet.RobotManager.Services;
public class WatchTimerAsync<T>(int Interval, Func<Task> Callback, LoggerController<T>? Logger) : IDisposable where T : class
{
private System.Threading.Timer? Timer;
private readonly Stopwatch Watch = new();
public bool Disposed;
private async void Handler(object? state)
{
try
{
Watch.Restart();
await 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(WatchTimerAsync<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;
}
~WatchTimerAsync()
{
Dispose(false);
}
}