private void InnerNextHandler(Task <bool> t) { if (t.IsFaulted) { ExceptionHelper.AddException(ref _parent._error, ExceptionHelper.Extract(t.Exception)); Done = true; if (TryDispose()) { ResumeHelper.Resume(ref _parent._resume); } } else if (t.Result) { Queue.Enqueue(_source.Current); if (TryDispose()) { if (Interlocked.Decrement(ref _outstanding) != 0) { MoveNext(); } ResumeHelper.Resume(ref _parent._resume); } } else { Done = true; if (TryDispose()) { ResumeHelper.Resume(ref _parent._resume); } } }
private void TimerHandler(Task t, T value, long idx) { if (!t.IsCanceled && SetLatest(value, idx)) { ResumeHelper.Resume(ref _resume); } }
private void Next(Task t) { if (t.IsCanceled || _cts.IsCancellationRequested) { ResumeHelper.Resume(ref _resume); return; } var value = Interlocked.Increment(ref _available); ResumeHelper.Resume(ref _resume); if (value != _end) { // FIXME compensate for drifts Task.Delay(_period, _cts.Token) .ContinueWith(NextAction, this); } }
public async ValueTask Next(T value) { if (_disposeRequested) { return; } await ResumeHelper.Await(ref _consumed); ResumeHelper.Clear(ref _consumed); if (_disposeRequested) { return; } Current = value; _hasValue = true; ResumeHelper.Resume(ref _valueReady); }
internal void SetTask(Task task) { _task = task.ContinueWith(async t => { if (_disposeRequested) { return; } await ResumeHelper.Await(ref _consumed); ResumeHelper.Clear(ref _consumed); if (_disposeRequested) { return; } _error = ExceptionHelper.Extract(t.Exception); ResumeHelper.Resume(ref _valueReady); }, Token); }
private void MainHandler(Task <bool> t) { if (t.IsCanceled) { _sourceError = new OperationCanceledException(); _sourceDone = true; _cancelOther.Cancel(); if (TryDisposeMain()) { ResumeHelper.Resume(ref _resume); } } else if (t.IsFaulted) { _sourceError = ExceptionHelper.Extract(t.Exception); _sourceDone = true; _cancelOther.Cancel(); if (TryDisposeMain()) { ResumeHelper.Resume(ref _resume); } } else if (t.Result) { _sourceValue = _source.Current; _sourceReady = true; if (TryDisposeMain()) { ResumeHelper.Resume(ref _resume); } } else { _sourceDone = true; _cancelOther.Cancel(); if (TryDisposeMain()) { ResumeHelper.Resume(ref _resume); } } }
private void OtherHandler(Task <bool> t) { if (t.IsCanceled) { _otherError = new OperationCanceledException(); _otherDone = true; _cancelMain.Cancel(); if (TryDisposeOther()) { ResumeHelper.Resume(ref _resume); } } if (t.IsFaulted) { _otherError = ExceptionHelper.Extract(t.Exception); _otherDone = true; _cancelMain.Cancel(); if (TryDisposeOther()) { ResumeHelper.Resume(ref _resume); } } else if (t.Result) { Interlocked.Exchange(ref _otherValue, _other.Current); if (TryDisposeOther()) { ResumeHelper.Resume(ref _resume); MoveNextOther(); } } else { _otherDone = true; if (TryDisposeOther()) { ResumeHelper.Resume(ref _resume); } } }
public async ValueTask <bool> MoveNextAsync() { ResumeHelper.Resume(ref _consumed); await ResumeHelper.Await(ref _valueReady); ResumeHelper.Clear(ref _valueReady); if (_hasValue) { _hasValue = false; return(true); } Current = default; var ex = _error; if (ex != null) { _error = null; throw ex; } return(false); }
private void Signal() { ResumeHelper.Resume(ref _resume); }
private void NextHandler(Task <bool> t) { if (t.IsFaulted) { ExceptionHelper.AddException(ref _error, ExceptionHelper.Extract(t.Exception)); _sourceDone = true; if (TryDispose()) { ResumeHelper.Resume(ref _resume); } } else if (t.Result) { var cts = CancellationTokenSource.CreateLinkedTokenSource(_ct); IAsyncEnumerator <TResult> src; try { src = _mapper(_source.Current).GetAsyncEnumerator(cts.Token); } catch (Exception ex) { ExceptionHelper.AddException(ref _error, ex); _sourceDone = true; src = null; if (TryDispose()) { ResumeHelper.Resume(ref _resume); return; } } if (src != null) { Interlocked.Increment(ref _disposeWip); var inner = new InnerHandler(src, this, cts); _inners.Enqueue(inner); if (_disposeRequested) { while (_inners.TryDequeue(out var inner2)) { inner2.Dispose(); } } if (TryDispose()) { inner.MoveNext(); if (Interlocked.Decrement(ref _sourceOutstanding) != 0) { MoveNextSource(); } ResumeHelper.Resume(ref _resume); } } } else { _sourceDone = true; if (TryDispose()) { ResumeHelper.Resume(ref _resume); } } }
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); } } }
public ValueTask DisposeAsync() { _disposeRequested = true; ResumeHelper.Resume(ref _consumed); return(new ValueTask(_task)); }