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);
         }
     }
 }
Ejemplo n.º 2
0
 private void TimerHandler(Task t, T value, long idx)
 {
     if (!t.IsCanceled && SetLatest(value, idx))
     {
         ResumeHelper.Resume(ref _resume);
     }
 }
Ejemplo n.º 3
0
            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);
            }
Ejemplo n.º 9
0
 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);
                    }
                }
            }
Ejemplo n.º 11
0
            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);
                    }
                }
            }
Ejemplo n.º 12
0
 public ValueTask DisposeAsync()
 {
     _disposeRequested = true;
     ResumeHelper.Resume(ref _consumed);
     return(new ValueTask(_task));
 }