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));
        }