public static IAsyncEnumerable<TSource> Finally<TSource>(this IAsyncEnumerable<TSource> source, Func<Task> finallyAction) { if (source == null) throw Error.ArgumentNull(nameof(source)); if (finallyAction == null) throw Error.ArgumentNull(nameof(finallyAction)); #if USE_ASYNC_ITERATOR return AsyncEnumerable.Create(Core); async IAsyncEnumerator<TSource> Core(CancellationToken cancellationToken) { try { await foreach (var item in AsyncEnumerableExtensions.WithCancellation(source, cancellationToken).ConfigureAwait(false)) { yield return item; } } finally { await finallyAction().ConfigureAwait(false); } } #else return new FinallyAsyncIteratorWithTask<TSource>(source, finallyAction); #endif }
public static IAsyncEnumerable <TSource> Expand <TSource>(this IAsyncEnumerable <TSource> source, Func <TSource, CancellationToken, ValueTask <IAsyncEnumerable <TSource> > > selector) { if (source == null) { throw Error.ArgumentNull(nameof(source)); } if (selector == null) { throw Error.ArgumentNull(nameof(selector)); } #if USE_ASYNC_ITERATOR return(AsyncEnumerable.Create(Core)); async IAsyncEnumerator <TSource> Core(CancellationToken cancellationToken) { var queue = new Queue <IAsyncEnumerable <TSource> >(); queue.Enqueue(source); while (queue.Count > 0) { await foreach (var item in AsyncEnumerableExtensions.WithCancellation(queue.Dequeue(), cancellationToken).ConfigureAwait(false)) { queue.Enqueue(await selector(item, cancellationToken).ConfigureAwait(false)); yield return(item); } } } #else return(new ExpandAsyncIteratorWithTaskAndCancellation <TSource>(source, selector)); #endif }
static async Task Core(IAsyncEnumerable <TSource> _source, Action <TSource> _action, CancellationToken _cancellationToken) { await foreach (var item in AsyncEnumerableExtensions.WithCancellation(_source, _cancellationToken).ConfigureAwait(false)) { _action(item); } }
public static IAsyncEnumerable <TResult> Select <TSource, TResult>(this IAsyncEnumerable <TSource> source, Func <TSource, int, TResult> selector) { if (source == null) { throw Error.ArgumentNull(nameof(source)); } if (selector == null) { throw Error.ArgumentNull(nameof(selector)); } #if USE_ASYNC_ITERATOR return(Create(Core)); async IAsyncEnumerator <TResult> Core(CancellationToken cancellationToken) { var index = -1; await foreach (var element in AsyncEnumerableExtensions.WithCancellation(source, cancellationToken).ConfigureAwait(false)) { checked { index++; } yield return(selector(element, index)); } } #else return(new SelectEnumerableWithIndexAsyncIterator <TSource, TResult>(source, selector)); #endif }
public static IAsyncEnumerable <TSource> Where <TSource>(this IAsyncEnumerable <TSource> source, Func <TSource, int, bool> predicate) { if (source == null) { throw Error.ArgumentNull(nameof(source)); } if (predicate == null) { throw Error.ArgumentNull(nameof(predicate)); } #if USE_ASYNC_ITERATOR return(Create(Core)); async IAsyncEnumerator <TSource> Core(CancellationToken cancellationToken) { var index = -1; await foreach (var element in AsyncEnumerableExtensions.WithCancellation(source, cancellationToken).ConfigureAwait(false)) { checked { index++; } if (predicate(element, index)) { yield return(element); } } } #else return(new WhereEnumerableWithIndexAsyncIterator <TSource>(source, predicate)); #endif }
public override async ValueTask <List <TSource> > ToListAsync(CancellationToken cancellationToken) { var count = await GetCountAsync(onlyIfCheap : true, cancellationToken).ConfigureAwait(false); var list = count == -1 ? new List <TSource>() : new List <TSource>(count); for (var n = _prepended; n != null; n = n.Linked) { list.Add(n.Item); } await foreach (var item in AsyncEnumerableExtensions.WithCancellation(_source, cancellationToken).ConfigureAwait(false)) { list.Add(item); } if (_appended != null) { using (var en2 = _appended.GetEnumerator(_appendCount)) { while (en2.MoveNext()) { list.Add(en2.Current); } } } return(list); }
internal static IAsyncEnumerable <TSource> TakeWhileAwaitCore <TSource>(this IAsyncEnumerable <TSource> source, Func <TSource, ValueTask <bool> > predicate) { if (source == null) { throw Error.ArgumentNull(nameof(source)); } if (predicate == null) { throw Error.ArgumentNull(nameof(predicate)); } #if USE_ASYNC_ITERATOR return(Create(Core)); async IAsyncEnumerator <TSource> Core(CancellationToken cancellationToken) { await foreach (var element in AsyncEnumerableExtensions.WithCancellation(source, cancellationToken).ConfigureAwait(false)) { if (!await predicate(element).ConfigureAwait(false)) { break; } yield return(element); } } #else return(new TakeWhileAsyncIteratorWithTask <TSource>(source, predicate)); #endif }
public static IAsyncEnumerable <TAccumulate> Scan <TSource, TAccumulate>(this IAsyncEnumerable <TSource> source, TAccumulate seed, Func <TAccumulate, TSource, TAccumulate> accumulator) { if (source == null) { throw Error.ArgumentNull(nameof(source)); } if (accumulator == null) { throw Error.ArgumentNull(nameof(accumulator)); } #if USE_ASYNC_ITERATOR return(AsyncEnumerable.Create(Core)); async IAsyncEnumerator <TAccumulate> Core(CancellationToken cancellationToken) { var res = seed; await foreach (var item in AsyncEnumerableExtensions.WithCancellation(source, cancellationToken).ConfigureAwait(false)) { res = accumulator(res, item); yield return(res); } } #else return(new ScanAsyncEnumerable <TSource, TAccumulate>(source, seed, accumulator)); #endif }
public static IAsyncEnumerable <TSource> Repeat <TSource>(this IAsyncEnumerable <TSource> source, int count) { if (source == null) { throw Error.ArgumentNull(nameof(source)); } if (count < 0) { throw Error.ArgumentOutOfRange(nameof(count)); } #if USE_ASYNC_ITERATOR return(AsyncEnumerable.Create(Core)); async IAsyncEnumerator <TSource> Core(CancellationToken cancellationToken) { for (var i = 0; i < count; i++) { await foreach (var item in AsyncEnumerableExtensions.WithCancellation(source, cancellationToken).ConfigureAwait(false)) { yield return(item); } } } #else return(new RepeatSequenceAsyncIterator <TSource>(source, count)); #endif }
public static async ValueTask AddRangeAsync <T>(this List <T> list, IAsyncEnumerable <T> collection, CancellationToken cancellationToken) { if (collection is IEnumerable <T> enumerable) { list.AddRange(enumerable); return; } if (collection is IAsyncIListProvider <T> listProvider) { var count = await listProvider.GetCountAsync(onlyIfCheap : true, cancellationToken).ConfigureAwait(false); if (count == 0) { return; } if (count > 0) { var newCount = list.Count + count; if (list.Capacity < newCount) { list.Capacity = newCount; } } } await foreach (var item in AsyncEnumerableExtensions.WithCancellation(collection, cancellationToken).ConfigureAwait(false)) { list.Add(item); } }
// NB: This is a non-standard LINQ operator, because we don't have a non-generic IAsyncEnumerable. // We're keeping it to enable `from T x in xs` binding in C#. public static IAsyncEnumerable <TResult> Cast <TResult>(this IAsyncEnumerable <object> source) { if (source == null) { throw Error.ArgumentNull(nameof(source)); } if (source is IAsyncEnumerable <TResult> typedSource) { return(typedSource); } #if USE_ASYNC_ITERATOR return(Create(Core)); async IAsyncEnumerator <TResult> Core(CancellationToken cancellationToken) { await foreach (var obj in AsyncEnumerableExtensions.WithCancellation(source, cancellationToken).ConfigureAwait(false)) { yield return((TResult)obj); } } #else return(new CastAsyncIterator <TResult>(source)); #endif }
public static IAsyncEnumerable <TSource> Intersect <TSource>(this IAsyncEnumerable <TSource> first, IAsyncEnumerable <TSource> second, IEqualityComparer <TSource> comparer) { if (first == null) { throw Error.ArgumentNull(nameof(first)); } if (second == null) { throw Error.ArgumentNull(nameof(second)); } #if USE_ASYNC_ITERATOR return(Create(Core)); async IAsyncEnumerator <TSource> Core(CancellationToken cancellationToken) { var set = new Set <TSource>(comparer); await foreach (var element in AsyncEnumerableExtensions.WithCancellation(second, cancellationToken).ConfigureAwait(false)) { set.Add(element); } await foreach (var element in AsyncEnumerableExtensions.WithCancellation(first, cancellationToken).ConfigureAwait(false)) { if (set.Remove(element)) { yield return(element); } } } #else return(new IntersectAsyncIterator <TSource>(first, second, comparer)); #endif }
public override async ValueTask <List <TSource> > ToListAsync(CancellationToken cancellationToken) { var count = await GetCountAsync(onlyIfCheap : true, cancellationToken).ConfigureAwait(false); cancellationToken.ThrowIfCancellationRequested(); var list = count == -1 ? new List <TSource>() : new List <TSource>(count); if (!_appending) { list.Add(_item); } await foreach (var item in AsyncEnumerableExtensions.WithCancellation(_source, cancellationToken).ConfigureAwait(false)) { list.Add(item); } if (_appending) { list.Add(_item); } return(list); }
public static IAsyncEnumerable <TSource> Using <TSource, TResource>(Func <CancellationToken, Task <TResource> > resourceFactory, Func <TResource, CancellationToken, ValueTask <IAsyncEnumerable <TSource> > > enumerableFactory) where TResource : IDisposable { if (resourceFactory == null) { throw Error.ArgumentNull(nameof(resourceFactory)); } if (enumerableFactory == null) { throw Error.ArgumentNull(nameof(enumerableFactory)); } #if USE_ASYNC_ITERATOR return(AsyncEnumerable.Create(Core)); async IAsyncEnumerator <TSource> Core(CancellationToken cancellationToken) { using (var resource = await resourceFactory(cancellationToken).ConfigureAwait(false)) { await foreach (var item in AsyncEnumerableExtensions.WithCancellation((await enumerableFactory(resource, cancellationToken).ConfigureAwait(false)), cancellationToken).ConfigureAwait(false)) { yield return(item); } } } #else return(new UsingAsyncIteratorWithTaskAndCancellation <TSource, TResource>(resourceFactory, enumerableFactory)); #endif }
static async ValueTask <List <TSource> > Core(IAsyncEnumerable <TSource> _source, CancellationToken _cancellationToken) { var list = new List <TSource>(); await foreach (var item in AsyncEnumerableExtensions.WithCancellation(_source, _cancellationToken).ConfigureAwait(false)) { list.Add(item); } return(list); }
static async ValueTask <HashSet <TSource> > Core(IAsyncEnumerable <TSource> _source, IEqualityComparer <TSource> _comparer, CancellationToken _cancellationToken) { var set = new HashSet <TSource>(_comparer); await foreach (var item in AsyncEnumerableExtensions.WithCancellation(_source, _cancellationToken).ConfigureAwait(false)) { set.Add(item); } return(set); }
static async ValueTask <bool> Core(IAsyncEnumerable <TSource> _source, Func <TSource, bool> _predicate, CancellationToken _cancellationToken) { await foreach (var item in AsyncEnumerableExtensions.WithCancellation(_source, _cancellationToken).ConfigureAwait(false)) { if (!_predicate(item)) { return(false); } } return(true); }
static async ValueTask <bool> Core(IAsyncEnumerable <TSource> _source, TSource _value, CancellationToken _cancellationToken) { await foreach (var item in AsyncEnumerableExtensions.WithCancellation(_source, _cancellationToken).ConfigureAwait(false)) { if (EqualityComparer <TSource> .Default.Equals(item, _value)) { return(true); } } return(false); }
private static async Task AwaitMoveNextAsyncAndDispose <T>(Task <bool> moveNextAsync, IAsyncEnumerator <T> enumerator) { if (enumerator != null) { await using (AsyncEnumerableExtensions.ConfigureAwait(enumerator, false)) { if (moveNextAsync != null) { await moveNextAsync.ConfigureAwait(false); } } } }
static async ValueTask <Dictionary <TKey, TSource> > Core(IAsyncEnumerable <TSource> _source, Func <TSource, TKey> _keySelector, IEqualityComparer <TKey> _comparer, CancellationToken _cancellationToken) { var d = new Dictionary <TKey, TSource>(_comparer); await foreach (var item in AsyncEnumerableExtensions.WithCancellation(_source, _cancellationToken).ConfigureAwait(false)) { var key = _keySelector(item); d.Add(key, item); } return(d); }
public static IAsyncEnumerable <IList <TSource> > Buffer <TSource>(this IAsyncEnumerable <TSource> source, int count, int skip) { if (source == null) { throw Error.ArgumentNull(nameof(source)); } if (count <= 0) { throw Error.ArgumentOutOfRange(nameof(count)); } if (skip <= 0) { throw Error.ArgumentOutOfRange(nameof(skip)); } #if USE_ASYNC_ITERATOR return(AsyncEnumerable.Create(Core)); async IAsyncEnumerator <IList <TSource> > Core(CancellationToken cancellationToken) { var buffers = new Queue <IList <TSource> >(); var index = 0; await foreach (var item in AsyncEnumerableExtensions.WithCancellation(source, cancellationToken).ConfigureAwait(false)) { if (index++ % skip == 0) { buffers.Enqueue(new List <TSource>(count)); } foreach (var buffer in buffers) { buffer.Add(item); } if (buffers.Count > 0 && buffers.Peek().Count == count) { yield return(buffers.Dequeue()); } } while (buffers.Count > 0) { yield return(buffers.Dequeue()); } } #else return(new BufferAsyncIterator <TSource>(source, count, skip)); #endif }
static async ValueTask <int> Core(IAsyncEnumerable <int> _source, CancellationToken _cancellationToken) { var sum = 0; await foreach (int value in AsyncEnumerableExtensions.WithCancellation(_source, _cancellationToken).ConfigureAwait(false)) { checked { sum += value; } } return(sum); }
static async ValueTask <int> Core(IAsyncEnumerable <TSource> _source, CancellationToken _cancellationToken) { var count = 0; await foreach (var item in AsyncEnumerableExtensions.WithCancellation(_source, _cancellationToken).ConfigureAwait(false)) { checked { count++; } } return(count); }
public override async ValueTask <TSource[]> ToArrayAsync(CancellationToken cancellationToken) { var count = await GetCountAsync(onlyIfCheap : true, cancellationToken).ConfigureAwait(false); if (count == -1) { return(await AsyncEnumerableHelpers.ToArray(this, cancellationToken).ConfigureAwait(false)); } cancellationToken.ThrowIfCancellationRequested(); var array = new TSource[count]; int index; if (_appending) { index = 0; } else { array[0] = _item; index = 1; } if (_source is ICollection <TSource> sourceCollection) { sourceCollection.CopyTo(array, index); } else { await foreach (var item in AsyncEnumerableExtensions.WithCancellation(_source, cancellationToken).ConfigureAwait(false)) { array[index] = item; ++index; } } if (_appending) { array[array.Length - 1] = _item; } return(array); }
private async Task <Set <TSource> > FillSetAsync(CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); var set = new Set <TSource>(_comparer); for (var index = 0; ; ++index) { var enumerable = GetEnumerable(index); if (enumerable == null) { return(set); } await foreach (var item in AsyncEnumerableExtensions.WithCancellation(enumerable, cancellationToken).ConfigureAwait(false)) { set.Add(item); } } }
public static IAsyncEnumerable <TSource> Defer <TSource>(Func <CancellationToken, Task <IAsyncEnumerable <TSource> > > factory) { if (factory == null) { throw Error.ArgumentNull(nameof(factory)); } #if USE_ASYNC_ITERATOR return(AsyncEnumerable.Create(Core)); async IAsyncEnumerator <TSource> Core(CancellationToken cancellationToken) { await foreach (var item in AsyncEnumerableExtensions.WithCancellation((await factory(cancellationToken).ConfigureAwait(false)), cancellationToken).ConfigureAwait(false)) { yield return(item); } } #else return(new AsyncDeferIteratorWithCancellation <TSource>(factory)); #endif }
public override async ValueTask <TSource[]> ToArrayAsync(CancellationToken cancellationToken) { var count = await GetCountAsync(onlyIfCheap : true, cancellationToken).ConfigureAwait(false); if (count == -1) { return(await AsyncEnumerableHelpers.ToArray(this, cancellationToken).ConfigureAwait(false)); } var array = new TSource[count]; var index = 0; for (var n = _prepended; n != null; n = n.Linked) { array[index] = n.Item; ++index; } if (_source is ICollection <TSource> sourceCollection) { sourceCollection.CopyTo(array, index); } else { await foreach (var item in AsyncEnumerableExtensions.WithCancellation(_source, cancellationToken).ConfigureAwait(false)) { array[index] = item; ++index; } } index = array.Length; for (var n = _appended; n != null; n = n.Linked) { --index; array[index] = n.Item; } return(array); }
public static IAsyncEnumerable <TSource> IgnoreElements <TSource>(this IAsyncEnumerable <TSource> source) { if (source == null) { throw Error.ArgumentNull(nameof(source)); } #if USE_ASYNC_ITERATOR return(AsyncEnumerable.Create(Core)); async IAsyncEnumerator <TSource> Core(CancellationToken cancellationToken) { await foreach (var _ in AsyncEnumerableExtensions.WithCancellation(source, cancellationToken).ConfigureAwait(false)) { } yield break; } #else return(new IgnoreElementsAsyncIterator <TSource>(source)); #endif }
public static IAsyncEnumerable <IList <TSource> > Buffer <TSource>(this IAsyncEnumerable <TSource> source, int count) { if (source == null) { throw Error.ArgumentNull(nameof(source)); } if (count <= 0) { throw Error.ArgumentOutOfRange(nameof(count)); } #if USE_ASYNC_ITERATOR return(AsyncEnumerable.Create(Core)); async IAsyncEnumerator <IList <TSource> > Core(CancellationToken cancellationToken) { var buffer = new List <TSource>(count); await foreach (var item in AsyncEnumerableExtensions.WithCancellation(source, cancellationToken).ConfigureAwait(false)) { buffer.Add(item); if (buffer.Count == count) { yield return(buffer); buffer = new List <TSource>(count); } } if (buffer.Count > 0) { yield return(buffer); } } #else return(new BufferAsyncIterator <TSource>(source, count, count)); #endif }
public async ValueTask <List <TSource> > ToListAsync(CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); var list = new List <TSource>(); for (var i = 0; ; i++) { var source = GetAsyncEnumerable(i); if (source == null) { break; } await foreach (var item in AsyncEnumerableExtensions.WithCancellation(source, cancellationToken).ConfigureAwait(false)) { list.Add(item); } } return(list); }