1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980 |
- // Licensed to the .NET Foundation under one or more agreements.
- // The .NET Foundation licenses this file to you under the Apache 2.0 License.
- // See the LICENSE file in the project root for more information.
- using System.Collections.Generic;
- using System.Threading;
- using System.Threading.Tasks;
- namespace System.Linq
- {
- internal abstract partial class AsyncIterator<TSource> : IAsyncEnumerable<TSource>, IAsyncEnumerator<TSource>
- {
- private readonly int _threadId;
- protected TSource _current;
- protected AsyncIteratorState _state = AsyncIteratorState.New;
- protected CancellationToken _cancellationToken;
- protected AsyncIterator()
- {
- _threadId = Environment.CurrentManagedThreadId;
- }
- public IAsyncEnumerator<TSource> GetAsyncEnumerator(CancellationToken cancellationToken)
- {
- var enumerator = _state == AsyncIteratorState.New && _threadId == Environment.CurrentManagedThreadId
- ? this
- : Clone();
- enumerator._state = AsyncIteratorState.Allocated;
- enumerator._cancellationToken = cancellationToken;
- return enumerator;
- }
- public virtual ValueTask DisposeAsync()
- {
- _current = default;
- _state = AsyncIteratorState.Disposed;
- return TaskExt.CompletedTask;
- }
- public TSource Current => _current;
- public async ValueTask<bool> MoveNextAsync()
- {
- // Note: MoveNext *must* be implemented as an async method to ensure
- // that any exceptions thrown from the MoveNextCore call are handled
- // by the try/catch, whether they're sync or async
- if (_state == AsyncIteratorState.Disposed)
- {
- return false;
- }
- try
- {
- return await MoveNextCore().ConfigureAwait(false);
- }
- catch
- {
- await DisposeAsync().ConfigureAwait(false);
- throw;
- }
- }
- public abstract AsyncIterator<TSource> Clone();
- protected abstract ValueTask<bool> MoveNextCore();
- }
- internal enum AsyncIteratorState
- {
- New = 0,
- Allocated = 1,
- Iterating = 2,
- Disposed = -1,
- }
- }
|