/// <inheritdoc />
            public void Dispose()
            {
                if (generatorTask == null)
                {
                    return;
                }
#endif
                // Notify the cancellation.
                if (lastCombinedCancellationTokenSource != taskCompletionTokenSource)
                {
                    lastCombinedCancellationTokenSource.Dispose();
                }
                taskCompletionTokenSource.Cancel();
                taskCompletionTokenSource.Dispose();
                // Do cleanup.
                buffer.Terminate();
                lastCombinedCancellationTokenSource = null;
                taskCompletionTokenSource           = null;
                lastMoveNextCancellationToken       = CancellationToken.None;
                buffer        = null;
                generatorTask = null;
#if CLR_FEATURE_ASYNC_STREAM
                return(new ValueTask());
#endif
            }
            /// <inheritdoc />
            public async Task <bool> MoveNext(CancellationToken cancellationToken)
#endif
            {
                if (generatorTask == null)
                {
                    buffer                    = new AsyncEnumerableBuffer <T>();
                    generatorTask             = generator(buffer, cancellationToken);
                    taskCompletionTokenSource = new CancellationTokenSource();
                    var forgetit = generatorTask.ContinueWith((_, cts) =>
                                                              ((CancellationTokenSource)cts).Cancel(), taskCompletionTokenSource,
                                                              taskCompletionTokenSource.Token);
                    lastCombinedCancellationTokenSource = taskCompletionTokenSource;
                }
                cancellationToken.ThrowIfCancellationRequested();
                if (buffer.TryTake(out var cur))
                {
                    Current = cur;
                    return(true);
                }
                // Currently no items available.
                if (generatorTask.IsCompleted)
                {
                    PropagateGeneratorException();
                    return(false);
                }
                // Slow route
                if (cancellationToken != lastMoveNextCancellationToken)
                {
                    lastMoveNextCancellationToken = cancellationToken;
                    if (lastCombinedCancellationTokenSource != taskCompletionTokenSource)
                    {
                        lastCombinedCancellationTokenSource.Dispose();
                    }
                    lastCombinedCancellationTokenSource = cancellationToken.CanBeCanceled
                        ? CancellationTokenSource.CreateLinkedTokenSource(taskCompletionTokenSource.Token, cancellationToken)
                        : taskCompletionTokenSource;
                }
                try
                {
                    Current = await buffer.Take(lastCombinedCancellationTokenSource.Token).ConfigureAwait(false);

                    return(true);
                }
                catch (OperationCanceledException)
                {
                    if (cancellationToken.IsCancellationRequested)
                    {
                        throw;
                    }
                    PropagateGeneratorException();
                    return(false);
                }
            }
Beispiel #3
0
 /// <inheritdoc />
 public void Dispose()
 {
     if (generatorTask == null)
     {
         return;
     }
     // Notify the cancellation.
     if (lastCombinedCancellationTokenSource != taskCompletionTokenSource)
     {
         lastCombinedCancellationTokenSource.Dispose();
     }
     taskCompletionTokenSource.Cancel();
     taskCompletionTokenSource.Dispose();
     // Do cleanup.
     buffer.Terminate();
     lastCombinedCancellationTokenSource = null;
     taskCompletionTokenSource           = null;
     lastMoveNextCancellationToken       = CancellationToken.None;
     buffer        = null;
     generatorTask = null;
 }