public async Task <IDisposable> WaitForReadiness(CancellationToken cancellationToken) { await _Semafore.WaitAsync(cancellationToken); var count = 0; var now = _Time.GetNow(); var target = now - _TimeSpan; LinkedListNode <DateTime> element = _TimeStamps.First, last = null; while ((element != null) && (element.Value > target)) { last = element; element = element.Next; count++; } if (count < _Count) { return(new DisposeAction(OnEnded)); } Debug.Assert(element == null); Debug.Assert(last != null); var timetoWait = last.Value.Add(_TimeSpan) - now; try { await _Time.GetDelay(timetoWait, cancellationToken); } catch (Exception) { _Semafore.Release(); throw; } return(new DisposeAction(OnEnded)); }