示例#1
0
 public static ISequence <T> Never <T>()
 {
     return(Sequence.Create <T>(context => Iterator.Create <T>(
                                    moveNext: c => c.AsTask().Then(() => TaskConstants.CanceledTask <bool>()),
                                    current: () => { throw new InvalidOperationException(); },
                                    cancel: Disposable.Empty,
                                    context: context)
                                ));
 }
示例#2
0
        protected override Task <bool> MoveNextInternal(CancellationToken cancel)
        {
            Task <bool> moveNextTask;

            for (;;)
            {
                if (inner == null)
                {
                    moveNextTask = source.MoveNext(cancel);
                    if (!moveNextTask.IsCompleted)
                    {
                        return(AwaitMoveNextOuterAsync(moveNextTask, cancel));
                    }
                    else if (moveNextTask.IsFaulted || moveNextTask.IsCanceled)
                    {
                        return(moveNextTask);
                    }
                    else if (!moveNextTask.Result)
                    {
                        return(TaskConstants.False);
                    }

                    lock (gate)
                    {
                        if (cancel.IsCancellationRequested)
                        {
                            return(TaskConstants.CanceledTask <bool>());
                        }

                        inner = source.Current.Start(source.Context);
                    }
                }

                moveNextTask = inner.MoveNext(cancel);
                if (!moveNextTask.IsCompleted)
                {
                    return(AwaitMoveNextInnerAsync(moveNextTask, cancel));
                }
                else if (moveNextTask.IsFaulted || moveNextTask.IsCanceled)
                {
                    return(moveNextTask);
                }

                if (moveNextTask.Result)
                {
                    current = inner.Current;
                    return(TaskConstants.True);
                }
                else
                {
                    inner = null;
                }
            }
        }
示例#3
0
        bool ProcessReadResults()
        {
            var cancel = cts.Token;

            lock (readers)
            {
                List <Exception> errors = null;

                int i = 0;
                while (i < activeReaderCount && !cancel.IsCancellationRequested)
                {
                    if (pendingReads[i] == null)
                    {
                        pendingReads[i] = readers[i].MoveNext(cancel);
                    }

                    var read = pendingReads[i];
                    if (!read.IsCompleted)                              // read result not yet available
                    {
                        ++i;
                    }
                    else if (read.IsFaulted)                            // source faulted
                    {
                        errors = read.Exception.InnerExceptions.ToList();
                        RemoveReader(i);
                        break;
                    }
                    else if (read.IsCanceled || !read.Result)           // source has no more data or read was canceled
                    {
                        RemoveReader(i);
                    }
                    else
                    {
                        available.Enqueue(readers[i].Current);

                        pendingReads[i] = readers[i].MoveNext(cancel);
                        ++i;
                    }
                }

                if (errors != null || cancel.IsCancellationRequested)
                {
                    Cancel();
                    available.Clear();
                    current         = default(T);
                    completedResult = errors != null?TaskEx.Throw <bool>(errors) : TaskConstants.CanceledTask <bool>();

                    return(false);
                }

                return(true);
            }
        }
示例#4
0
        public void Cancel()
        {
            cts.Cancel();

            lock (readers)
            {
                completedResult = TaskConstants.CanceledTask <bool>();

                for (int i = 0; i < activeReaderCount; ++i)
                {
                    readers[i].Cancel();
                }
            }
        }
示例#5
0
        public Task <bool> MoveNext(CancellationToken cancel)
        {
            lock (selector)
            {
                if (moveNextTask != null && !moveNextTask.IsCompleted)
                {
                    return(TaskEx.Throw <bool>(new OverlappingMoveNextException()));
                }

                if (cts.IsCancellationRequested)
                {
                    return(TaskConstants.CanceledTask <bool>());
                }

                ClearCurrent();
                moveNextTask = source.MoveNext(cancel);
                if (!moveNextTask.IsCompleted)
                {
                    return(AwaitMoveNext());
                }

                if (moveNextTask.IsFaulted)
                {
                    Cancel();
                    return(moveNextTask);
                }

                if (moveNextTask.Result)
                {
                    try
                    {
                        current = selector(source.Current);
                        return(TaskConstants.True);
                    }
                    catch (Exception e)
                    {
                        return(TaskEx.Throw <bool>(e));
                    }
                }
                else
                {
                    return(TaskConstants.False);
                }
            }
        }
示例#6
0
        public Task <bool> MoveNext(CancellationToken cancel)
        {
            if (cts.IsCancellationRequested)
            {
                return(TaskConstants.CanceledTask <bool>());
            }

            var moveNextTask = MoveNextInternal(cancel);

            if (!moveNextTask.IsCompleted)
            {
                return(AwaitMoveNextInternal(moveNextTask));
            }

            if (moveNextTask.IsFaulted)
            {
                ClearCurrent();
                Cancel();
            }

            return(moveNextTask);
        }
示例#7
0
        public Task <bool> MoveNext(CancellationToken cancel)
        {
            if (completed)
            {
                return(TaskConstants.False);
            }

            try
            {
                // start all move next operations
                bool allCompletedSynchronously = true;
                for (int i = 0; i < iterators.Length; ++i)
                {
                    moveNextTasks[i] = iterators[i].MoveNext(cancel);           // exceptions during MoveNext() should be communicated through the task object
                    if (!moveNextTasks[i].IsCompleted)
                    {
                        allCompletedSynchronously = false;
                    }
                }

                if (!allCompletedSynchronously)
                {
                    // fall back to asynchronous await Task.WhenAll(moveNextTasks) ...
                    return(MoveNextInternalAsync(cancel));
                }

                for (int i = 0; i < iterators.Length; ++i)
                {
                    if (moveNextTasks[i].Result)
                    {
                        current[i] = iterators[i].Current;
                    }
                    else
                    {
                        // at least one iterator reached the end of its sequence, stop here
                        completed = true;
                        ClearCurrentAndStop();
                        return(TaskConstants.False);
                    }
                }
            }
            catch (AggregateException ae)
            {
                ClearCurrentAndStop();

                if (moveNextTasks.Any(x => x.IsFaulted))
                {
                    // one or more move next operation sgenerated an error
                    var errorList = moveNextTasks.Where(x => x.IsFaulted).SelectMany(x => x.Exception.InnerExceptions).ToArray();
                    return(TaskEx.Throw <bool>(errorList));
                }
                else if (ae.InnerException is OperationCanceledException || moveNextTasks.Any(x => x.IsCanceled))
                {
                    // one move next operation was canceled
                    return(TaskConstants.CanceledTask <bool>());
                }
                else
                {
                    return(TaskEx.Throw <bool>(ae));
                }
            }

            return(TaskConstants.True);
        }
示例#8
0
        public Task <bool> MoveNext(CancellationToken cancel)
        {
            lock (gate)
            {
                if (completed)
                {
                    return(TaskConstants.False);
                }

                if (!AllMoveNextCallsCompleted())
                {
                    return(TaskEx.Throw <bool>(new OverlappingMoveNextException()));
                }

                current = default(T);

                if (cts.IsCancellationRequested || cancel.IsCancellationRequested)
                {
                    return(TaskConstants.CanceledTask <bool>());
                }

                try
                {
                    // start all move next operations
                    StartMoveNextOperations(cancel);

                    // check if all MoveNext() operations executed synchronously
                    if (!AllMoveNextCallsCompleted())
                    {
                        // fall back to asynchronous await Task.WhenAll(moveNextTasks) ...
                        return(MoveNextInternalAsync(cancel));
                    }

                    for (int i = 0; i < moveNextTasks.Length; ++i)
                    {
                        if (!moveNextTasks[i].Result)
                        {
                            // at least one iterator reached the end of its sequence, stop here
                            completed = true;
                            ClearCurrentAndStop();
                            return(TaskConstants.False);
                        }
                    }
                }
                catch (AggregateException ae)
                {
                    ClearCurrentAndStop();

                    if (moveNextTasks.Any(x => x.IsFaulted))
                    {
                        // one or more move next operation sgenerated an error
                        var errorList = moveNextTasks.Where(x => x.IsFaulted).SelectMany(x => x.Exception.InnerExceptions).ToArray();
                        return(TaskEx.Throw <bool>(errorList));
                    }
                    else if (ae.InnerException is OperationCanceledException || moveNextTasks.Any(x => x.IsCanceled))
                    {
                        // one move next operation was canceled
                        return(TaskConstants.CanceledTask <bool>());
                    }
                    else
                    {
                        return(TaskEx.Throw <bool>(ae));
                    }
                }

                try
                {
                    if (cts.IsCancellationRequested)
                    {
                        return(TaskConstants.CanceledTask <bool>());
                    }

                    current = Select();
                }
                catch (Exception error)
                {
                    return(TaskEx.Throw <bool>(error));
                }

                return(TaskConstants.True);
            }
        }
示例#9
0
        protected override Task <bool> MoveNextInternal(CancellationToken cancel)
        {
            if (bindResult == null)      // double-checked locking
            {
                lock (gate)
                {
                    if (cts.IsCancellationRequested)
                    {
                        return(TaskEx.Throw <bool>(new Exception("Iterator was stopped")));
                    }

                    if (bindResult == null)
                    {
                        try
                        {
                            // try to bind sources synchronously
                            var bindTask = source.ToListAsync(cancel);
                            if (!bindTask.IsCompleted)
                            {
                                bindResult = ContinueBindAsync(bindTask, cancel);
                                return(bindResult);
                            }
                            else if (bindTask.IsFaulted)
                            {
                                return(TaskEx.Throw <bool>(bindTask.Exception.InnerExceptions));
                            }
                            else if (bindTask.IsCanceled)
                            {
                                return(TaskConstants.CanceledTask <bool>());
                            }

                            // we got the sequence list synchronously, now start the source sequences and pass our own context
                            var sourceSequences = bindTask.Result;
                            this.current       = new T[sourceSequences.Count];
                            this.moveNextTasks = new Task <bool> [sourceSequences.Count];

                            if (cancel.IsCancellationRequested)
                            {
                                return(TaskConstants.CanceledTask <bool>());
                            }

                            iterators       = sourceSequences.Select(x => x.Start(source.Context)).ToList();
                            this.bindResult = TaskConstants.True;
                        }
                        catch (Exception e)
                        {
                            return(TaskEx.Throw <bool>(e));
                        }
                    }
                }
            }

            if (!bindResult.IsCompleted)
            {
                return(TaskEx.Throw <bool>(new Exception("Previous MoveNext() has not been completed.")));
            }
            else if (bindResult.IsFaulted || bindResult.IsCanceled)
            {
                return(bindResult);
            }

            if (completed)
            {
                return(TaskConstants.False);
            }

            try
            {
                // start all move next operations
                bool allCompletedSynchronously = true;
                for (int i = 0; i < iterators.Count; ++i)
                {
                    moveNextTasks[i] = iterators[i].MoveNext(cancel);           // exceptions during MoveNext() should be communicated through the task object
                    if (!moveNextTasks[i].IsCompleted)
                    {
                        allCompletedSynchronously = false;
                    }
                }

                if (!allCompletedSynchronously)
                {
                    // fall back to asynchronous await Task.WhenAll(moveNextTasks) ...
                    return(MoveNextInternalAsync(cancel));
                }

                for (int i = 0; i < iterators.Count; ++i)
                {
                    if (moveNextTasks[i].Result)
                    {
                        current[i] = iterators[i].Current;
                    }
                    else
                    {
                        // at least one iterator reached the end of its sequence, stop here
                        completed = true;
                        ClearCurrent();
                        CancelInternal();
                        return(TaskConstants.False);
                    }
                }
            }
            catch (AggregateException ae)
            {
                ClearCurrent();

                if (moveNextTasks.Any(x => x.IsFaulted))
                {
                    // one or more move next operation sgenerated an error
                    var errorList = moveNextTasks.Where(x => x.IsFaulted).SelectMany(x => x.Exception.InnerExceptions).ToArray();
                    return(TaskEx.Throw <bool>(errorList));
                }
                else if (ae.InnerException is OperationCanceledException || moveNextTasks.Any(x => x.IsCanceled))
                {
                    // one move next operation was canceled
                    return(TaskConstants.CanceledTask <bool>());
                }
                else
                {
                    return(TaskEx.Throw <bool>(ae));
                }
            }

            return(TaskConstants.True);
        }