public Task <bool> MoveNext(CancellationToken cancel) { lock (factory) { if (producerTask != null && !producerTask.IsCompleted) { return(TaskEx.Throw <bool>(new OverlappingMoveNextException())); } if (remaining <= 0) { producerTask = null; return(TaskConstants.False); } --remaining; producerTask = factory(context, cancel); if (producerTask.IsCompleted && !producerTask.IsFaulted && !producerTask.IsCanceled) { return(TaskConstants.True); } return(WaitResultAsync()); } }
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); } }
public static IWritable Create(Action <Stream> writeToFunc, IDisposable resource = null) { return(Create((stream, cancel) => { try { writeToFunc(stream); return TaskConstants.Completed; } catch (Exception ex) { return TaskEx.Throw(ex); } }, resource)); }
public Task <bool> MoveNext(CancellationToken cancel) { if (stopped) { return(TaskEx.Throw <bool>(new ObjectDisposedException("AnonymousIterator", "The sequence iterator has been stopped."))); } try { return(next(cancel)); } catch (Exception e) { Cancel(); return(TaskEx.Throw <bool>(e)); } }
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); } } }
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); }
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); } }
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); }