public ValueTask DisposeAsync() { CancellationHelper.Cancel(ref _cts); if (Interlocked.Increment(ref _disposeWip) == 1) { if (_emitLast) { _emitLastItem = default; } return(_source.DisposeAsync()); } return(ResumeHelper.Await(ref _disposeTask)); }
private void HandleMain(Task <bool> t) { if (t.IsCanceled) { _error = new OperationCanceledException(); _done = true; if (TryDispose()) { ResumeHelper.Resume(ref _resume); } } else if (t.IsFaulted) { CancellationHelper.Cancel(ref _cts); if (_emitLast) { var idx = _sourceIndex; if (idx != 0) { SetLatest(_emitLastItem, idx + 1); _emitLastItem = default; } } _error = ExceptionHelper.Extract(t.Exception); _done = true; if (TryDispose()) { ResumeHelper.Resume(ref _resume); } } else if (t.Result) { Volatile.Read(ref _cts)?.Cancel(); var v = _source.Current; if (TryDispose()) { if (_emitLast) { _emitLastItem = v; } var idx = ++_sourceIndex; var newCts = CancellationTokenSource.CreateLinkedTokenSource(_ct); if (CancellationHelper.Replace(ref _cts, newCts)) { Task.Delay(_delay, newCts.Token) .ContinueWith(tt => TimerHandler(tt, v, idx), newCts.Token); MoveNext(); } } } else { CancellationHelper.Cancel(ref _cts); if (_emitLast) { var idx = _sourceIndex; if (idx != 0) { SetLatest(_emitLastItem, idx + 1); _emitLastItem = default; } } _done = true; if (TryDispose()) { ResumeHelper.Resume(ref _resume); } } }