private async Task <bool> ReadAnotherBatchAsync(CancellationToken cancellationToken)
            {
                Contract.Requires(m_itemsRemainingInChunk == 0 && m_currentOffsetInChunk == -1 && !m_outOfChunks);

                // start reading the next batch
                if (await m_chunkIterator.MoveNext(cancellationToken).ConfigureAwait(false))
                {                 // we got a new chunk !
                    var chunk = m_chunkIterator.Current;

                    //note: if the range is empty, we may have an empty chunk, that is equivalent to no chunk
                    if (chunk != null && chunk.Length > 0)
                    {
#if DEBUG_RANGE_ITERATOR
                        Debug.WriteLine("Got a new chunk from page iterator: " + chunk.Length);
#endif
                        m_chunk = chunk;
                        m_itemsRemainingInChunk = chunk.Length;

                        // transform the first one
                        return(ProcessNextItem());
                    }
#if DEBUG_RANGE_ITERATOR
                    Debug.WriteLine("Got empty chunk from page iterator!");
#endif
                }

#if DEBUG_RANGE_ITERATOR
                Debug.WriteLine("No more chunks from page iterator");
#endif
                m_outOfChunks = true;
                return(Completed());
            }
Ejemplo n.º 2
0
        /// <summary>Run the pump until the inner iterator is done, an error occurs, or the cancellation token is fired</summary>
        public async Task PumpAsync(CancellationToken ct)
        {
            if (m_state != STATE_IDLE)
            {
                if (m_state >= STATE_FAILED)
                {
                    throw new InvalidOperationException("The iterator pump has already completed once");
                }
                else
                {
                    throw new InvalidOperationException("The iterator pump is already running");
                }
            }

            try
            {
                while (!ct.IsCancellationRequested)
                {
                    LogDebug("waiting for next");
                    m_state = STATE_WAITING_FOR_NEXT;
                    if (!(await m_iterator.MoveNext(ct).ConfigureAwait(false)))
                    {
                        LogDebug("completed");
                        m_state = STATE_DONE;
                        m_target.OnCompleted();
                        return;
                    }

                    LogDebug("got item, publishing...");
                    m_state = STATE_PUBLISHING_TO_TARGET;
                    await m_target.OnNextAsync(m_iterator.Current, ct).ConfigureAwait(false);
                }

                // push the cancellation on the queue
                OnError(ExceptionDispatchInfo.Capture(new OperationCanceledException(ct)));
                // and throw!
            }
            catch (Exception e)
            {
                LogDebug("failed... (" + m_state + ") : " + e.Message);
                if (m_state == STATE_FAILED)
                {                 // already signaled the target, just throw
                    throw;
                }

                // push the error on the queue, and eat the error
                OnError(ExceptionDispatchInfo.Capture(e));
            }
            finally
            {
                if (m_state != STATE_FAILED)
                {
                    m_state = STATE_DONE;
                }
                LogDebug("stopped (" + m_state + ")");
            }
        }
Ejemplo n.º 3
0
			public Task<bool> MoveNext(CancellationToken cancellationToken)
			{
				return m_iterator.MoveNext(cancellationToken);
			}