Laservall_solidworks_inject/Server/HeartbeatMonitor.cs

61 lines
1.5 KiB
C#
Raw Permalink Normal View History

using System;
using System.Threading;
namespace Laservall.Solidworks.Server
{
internal sealed class HeartbeatMonitor : IDisposable
{
private readonly TimeSpan _timeout;
private readonly Action _onTimeout;
private Timer _timer;
private long _lastPingTicks;
private bool _running;
private bool _disposed;
public HeartbeatMonitor(TimeSpan timeout, Action onTimeout)
{
_timeout = timeout;
_onTimeout = onTimeout;
}
public void Start()
{
_lastPingTicks = DateTime.UtcNow.Ticks;
_running = true;
_timer = new Timer(CheckTimeout, null, _timeout, _timeout);
}
public void Stop()
{
_running = false;
_timer?.Change(Timeout.Infinite, Timeout.Infinite);
}
public void Ping()
{
Interlocked.Exchange(ref _lastPingTicks, DateTime.UtcNow.Ticks);
}
private void CheckTimeout(object state)
{
if (!_running) return;
long lastPing = Interlocked.Read(ref _lastPingTicks);
var elapsed = TimeSpan.FromTicks(DateTime.UtcNow.Ticks - lastPing);
if (elapsed > _timeout)
{
_running = false;
_onTimeout?.Invoke();
}
}
public void Dispose()
{
if (_disposed) return;
_disposed = true;
_timer?.Dispose();
}
}
}