Example #1
0
        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
        }
Example #2
0
        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
        }
Example #3
0
        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
        }
Example #4
0
            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);
            }
Example #5
0
 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);
     }
 }
Example #6
0
            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);
            }
Example #7
0
        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
        }
Example #8
0
        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
        }
Example #9
0
        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
        }
Example #10
0
        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
        }
Example #11
0
        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);
            }
        }
Example #12
0
        // 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
        }
Example #13
0
        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
        }
Example #14
0
        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
        }
Example #15
0
            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);
            }
Example #16
0
            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);
            }
Example #17
0
                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);
                }
Example #18
0
            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);
            }
Example #19
0
            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);
            }
Example #20
0
        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
        }
Example #21
0
            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);
            }
Example #22
0
            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);
            }
Example #23
0
            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);
            }
Example #24
0
            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);
                    }
                }
            }
Example #25
0
        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
        }
Example #26
0
            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);
            }
Example #27
0
        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
        }
Example #28
0
        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
        }
Example #29
0
            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);
            }
Example #30
0
            static async ValueTask <TSource> Core(IAsyncEnumerable <TSource> _source, int _index, CancellationToken _cancellationToken)
            {
                if (_source is IAsyncPartition <TSource> p)
                {
                    var first = await p.TryGetElementAtAsync(_index, _cancellationToken).ConfigureAwait(false);

                    if (first.HasValue)
                    {
                        return(first.Value);
                    }
                }
                else
                {
                    if (_source is IList <TSource> list)
                    {
                        return(list[_index]);
                    }

                    if (_index >= 0)
                    {
                        await foreach (var item in AsyncEnumerableExtensions.WithCancellation(_source, _cancellationToken).ConfigureAwait(false))
                        {
                            if (_index == 0)
                            {
                                return(item);
                            }

                            _index--;
                        }
                    }
                }

                // NB: Even though index is captured, no closure is created.
                //     The nameof expression is lowered to a literal prior to creating closures.

                throw Error.ArgumentOutOfRange(nameof(index));
            }