/// <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); } }
/// <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; }