using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace LB_SmartVision { public sealed class PausableHeartbeatAsync : IAsyncDisposable { private readonly CancellationTokenSource _cts = new(); private readonly AsyncManualResetEvent _pauseEvent = new(true); // 初始为已设置(未暂停) private readonly Task _loopTask; private readonly Func _sendHeartbeatAsync; private readonly TimeSpan _interval; public PausableHeartbeatAsync(Func sendHeartbeatAsync, TimeSpan interval) { _sendHeartbeatAsync = sendHeartbeatAsync; _interval = interval; _loopTask = Task.Run(RunAsync); } private async Task RunAsync() { using var timer = new PeriodicTimer(_interval); try { while (await timer.WaitForNextTickAsync(_cts.Token)) { // 等待暂停状态解除(若未暂停则立即通过) await _pauseEvent.WaitAsync(_cts.Token); try { await _sendHeartbeatAsync(); } catch (Exception ex) { Console.WriteLine($"[Async Heartbeat] 异常: {ex.Message}"); } } } catch (OperationCanceledException) { } } public void Pause() => _pauseEvent.Reset(); public void Resume() => _pauseEvent.Set(); public async Task StopAsync() { _cts.Cancel(); Resume(); // 防止 WaitAsync 永久阻塞 await _loopTask.ConfigureAwait(false); } public async ValueTask DisposeAsync() { await StopAsync(); _cts.Dispose(); } // 简单的异步手动重置事件辅助类 private class AsyncManualResetEvent { private volatile TaskCompletionSource _tcs = new(); private readonly object _lock = new(); public AsyncManualResetEvent(bool initialState) { if (initialState) _tcs.TrySetResult(true); } public Task WaitAsync(CancellationToken token = default) { return _tcs.Task.WaitAsync(token); } public void Set() { lock (_lock) { _tcs.TrySetResult(true); } } public void Reset() { lock (_lock) { if (_tcs.Task.IsCompleted) _tcs = new TaskCompletionSource(); } } } } }