示例#1
0
        public static IAsyncEnumerable <R> Select <T, R>(this IAsyncEnumerable <T> source, Func <T, Task <R> > selector)
        {
            if (source == null)
            {
                throw new ArgumentNullException(nameof(source));
            }
            if (selector == null)
            {
                throw new ArgumentNullException(nameof(selector));
            }

#if CSHARP8
            return(Iterator());

            async IAsyncEnumerable <R> Iterator()
            {
                foreach await(var item in source.ConfigureAwait(false))
                {
                    yield return(selector(item).ConfigureAwait(false));
                }
            }
#elif MONADIC
            return(source.SelectMany(async x => Return(await selector(x).ConfigureAwait(false))));
#else
            return(new SelectAsyncIteratorWithAsyncSelector <T, R>(source, selector));
#endif
        }
示例#2
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="fromSequenceNumber"></param>
        /// <param name="maxMessages"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        internal async IAsyncEnumerable <ServiceBusMessage> PeekRangeBySequenceInternal(
            long?fromSequenceNumber,
            int maxMessages = 1,
            [EnumeratorCancellation]
            CancellationToken cancellationToken = default)
        {
            RetriableContext  context    = CreateRetriableContext(cancellationToken);
            ReceivingAmqpLink openedLink =
                await context.RunOperation(
                    async() => await Consumer.ReceiveLink.GetOrCreateAsync(context.TimeSpan)
                    .ConfigureAwait(false))
                .ConfigureAwait(false);

            var source = (Source)openedLink.Settings.Source;

            if (source.FilterSet.TryGetValue <string>(AmqpClientConstants.SessionFilterName, out var tempSessionId))
            {
                // If one of the constructors not accepting a SessionId was used, the broker will determine which session to send messages from.
                SessionId = tempSessionId;
            }
            IAsyncEnumerable <ServiceBusMessage> ret = PeekRangeBySequenceInternal(
                fromSequenceNumber: fromSequenceNumber,
                maxMessages: maxMessages,
                sessionId: SessionId,
                cancellationToken: cancellationToken);

            await foreach (ServiceBusMessage msg in ret.ConfigureAwait(false))
            {
                yield return(msg);
            }
        }
            private async Task <IEnumerable <T> > ConvertBlobs(IAsyncEnumerable <BlobItem> blobItems, BlobContainerClient blobContainerClient)
            {
                var list = new List <T>();

                await foreach (var blobItem in blobItems.ConfigureAwait(false))
                {
                    BlobBaseClient src = null;
                    switch (blobItem.Properties.BlobType)
                    {
                    case BlobType.Block:
                        src = blobContainerClient.GetBlockBlobClient(blobItem.Name);
                        break;

                    case BlobType.Append:
                        src = blobContainerClient.GetAppendBlobClient(blobItem.Name);
                        break;

                    case BlobType.Page:
                        src = blobContainerClient.GetPageBlobClient(blobItem.Name);
                        break;

                    default:
                        throw new InvalidOperationException($"Unexpected blob type {blobItem.Properties.BlobType}");
                    }

                    var funcCtx  = new FunctionBindingContext(Guid.Empty, CancellationToken.None);
                    var valueCtx = new ValueBindingContext(funcCtx, CancellationToken.None);

                    var converted = await _converter(src, null, valueCtx).ConfigureAwait(false);

                    list.Add(converted);
                }

                return(list);
            }
示例#4
0
        public static Task <int?> MinAsync(this IAsyncEnumerable <int?> source, CancellationToken token = default)
        {
            if (source == null)
            {
                throw new ArgumentNullException(nameof(source));
            }

            return(Core());

            async Task <int?> Core()
            {
                token.ThrowIfCancellationRequested();

                int?min = default;

                foreach await(var item in source.ConfigureAwait(false))
                {
                    token.ThrowIfCancellationRequested();

                    if (!min.HasValue || item < min)
                    {
                        min = item;
                    }
                }

                return(min);
            }
        }
        /// <summary>
        /// Maps the <see cref="IAsyncEnumerable{TSource}"/> into <see cref="IAsyncEnumerable{TDestination}"/>.
        /// </summary>
        /// <typeparam name="TSource">The type of the source objects.</typeparam>
        /// <typeparam name="TDestination">The type of the destination objects.</typeparam>
        /// <param name="mapper">The mapper.</param>
        /// <param name="source">The source asynchronous enumerable.</param>
        /// <param name="cancellationToken">The cancellation token.</param>
        /// <returns>An <see cref="IAsyncEnumerable{TDestination}"/> collection.</returns>
        /// <exception cref="ArgumentNullException">The <paramref name="mapper"/> or <paramref name="source"/> is
        /// <c>null</c>.</exception>
        public static async IAsyncEnumerable <TDestination> MapAsyncEnumerable <TSource, TDestination>(
            this IAsyncMapper <TSource, TDestination> mapper,
            IAsyncEnumerable <TSource> source,
            [EnumeratorCancellation] CancellationToken cancellationToken = default)
            where TDestination : new()
        {
            if (mapper is null)
            {
                throw new ArgumentNullException(nameof(mapper));
            }

            if (source is null)
            {
                throw new ArgumentNullException(nameof(source));
            }

            await foreach (var sourceItem in source.ConfigureAwait(false).WithCancellation(cancellationToken))
            {
                var destinationItem = Factory <TDestination> .CreateInstance();

                await mapper.MapAsync(sourceItem, destinationItem).ConfigureAwait(false);

                yield return(destinationItem);
            }
        }
示例#6
0
    /// <summary>
    /// Transform a sequence of bytes with a length prefix into a sequence of byte arrays.
    /// </summary>
    public static async IAsyncEnumerable <byte[]> ToArraysFromBytesWithLengthPrefix(this IAsyncEnumerable <byte> source)
    {
        ArgumentNullException.ThrowIfNull(source);

        int length = -1;

        using MemoryStream ms = new();
        await foreach (byte b in source.ConfigureAwait(false))
        {
            ms.WriteByte(b);
            if (length == -1 && ms.Position == 4)
            {
                length = DecodeMessageLength(ms);
                ms.SetLength(0);
            }
            else if (length == ms.Length)
            {
                yield return(ms.ToArray()); // array copy

                length = -1;
                ms.SetLength(0);
            }
        }
        if (ms.Position != 0)
        {
            throw new InvalidDataException("ToArraysFromBytesWithLengthPrefix: invalid termination.");
        }
    }
示例#7
0
        public static IAsyncEnumerable <T> Where <T>(this IAsyncEnumerable <T> source, Func <T, Task <bool> > predicate)
        {
            if (source == null)
            {
                throw new ArgumentNullException(nameof(source));
            }
            if (predicate == null)
            {
                throw new ArgumentNullException(nameof(predicate));
            }

#if CSHARP8
            return(Iterator());

            async IAsyncEnumerable <T> Iterator()
            {
                foreach await(var item in source.ConfigureAwait(false))
                {
                    if (await predicate(item).ConfigureAwait(false))
                    {
                        yield return(item);
                    }
                }
            }
#elif MONADIC
            return(source.SelectMany(async x => await predicate(x).ConfigureAwait(false) ? Return(x) : Empty <T>()));
#else
            return(new WhereAsyncIteratorWithAsyncPredicate <T>(source, predicate));
#endif
        }
 private static async IAsyncEnumerable <string> Greet(IAsyncEnumerable <string> names, string greet)
 {
     await foreach (var i in names.ConfigureAwait(false))
     {
         yield return(greet + " " + i + "!");
     }
 }
        private async Task <UpgradeStep?> GetNextStepInternalAsync(IAsyncEnumerable <UpgradeStep> steps, IUpgradeContext context, CancellationToken token)
        {
            if (context is null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            // This iterates through all incomplete steps, returning children before parents but initializing parents before children.
            // This is intentional because the expectation is that parents are initialized before children, but children are applied before parents.
            //
            // For each step, the expected order of operations is:
            // 1. Initialize the step
            // 2. Recurse into sub-steps (if needed)
            // 3. Return the step if it's not completed, or
            //    continue iterating with the next step if it is.
            await foreach (var step in steps.ConfigureAwait(false))
            {
                token.ThrowIfCancellationRequested();

                if (step.Status == UpgradeStepStatus.Unknown)
                {
                    // It is not necessary to iterate through sub-steps because parents steps are
                    // expected to initialize their children during their own initialization
                    _logger.LogInformation("Initializing upgrade step {StepTitle}", step.Title);
                    await step.InitializeAsync(context, token).ConfigureAwait(false);

                    // This is actually not dead code. The above sentence InitializeAsync(...) call will potentially change the status.
#pragma warning disable CA1508 // Avoid dead conditional code
                    if (step.Status == UpgradeStepStatus.Unknown)
#pragma warning restore CA1508 // Avoid dead conditional code
                    {
                        _logger.LogError("Upgrade step initialization failed for step {StepTitle}", step.Title);
                        throw new InvalidOperationException($"Step must not have unknown status after initialization. Step: {step.Title}");
                    }
                    else
                    {
                        _logger.LogDebug("Step {StepTitle} initialized", step.Title);
                    }
                }

                if (step.SubSteps.Any())
                {
                    var applicableSubSteps = GetStepsForContextAsync(context, step.SubSteps);
                    var nextSubStep        = await GetNextStepInternalAsync(applicableSubSteps, context, token).ConfigureAwait(false);

                    if (nextSubStep is not null)
                    {
                        return(nextSubStep);
                    }
                }

                if (!step.IsDone)
                {
                    return(step);
                }
            }

            return(null);
        }
 private static async IAsyncEnumerable <object> ConvertEnumerable <T>(
     IAsyncEnumerable <T> enumerable)
 {
     await foreach (T item in enumerable.ConfigureAwait(false))
     {
         yield return(item);
     }
 }
        // This method exists, because we have to put ConfigureAwait(false) on IAsyncEnumerable.
        public static async Task <T?> FirstOrDefaultAsync <T>(this IAsyncEnumerable <T> enumerable)
        {
            await foreach (var item in enumerable.ConfigureAwait(false))
            {
                return(item);
            }

            return(default);
示例#12
0
        public static async Task <T?> FirstOrDefaultAsync <T>(this IAsyncEnumerable <T> enumerable)
            where T : class
        {
            await foreach (var current in enumerable.ConfigureAwait(false))
            {
                return(current);
            }

            return(default);
示例#13
0
 public AsyncEnumerableCollection(
     IAsyncEnumerable <T> valueEnumerable,
     CancellationToken cancellation = default)
 {
     _enumerator = valueEnumerable
                   .ConfigureAwait(true)
                   .WithCancellation(cancellation)
                   .GetAsyncEnumerator();
 }
示例#14
0
        public static async Task <TElement> FirstOrDefault <TElement>(this IAsyncEnumerable <TElement> elements)
            where TElement : class, IAsyncListElement
        {
            await foreach (var element in elements.ConfigureAwait(false))
            {
                return(element);
            }

            return(default);
示例#15
0
 public static async IAsyncEnumerable <Illust> R18(this IAsyncEnumerable <Illust> source)
 {
     await foreach (var i in source.ConfigureAwait(false))
     {
         if (i.IsR18)
         {
             yield return(i);
         }
     }
 }
示例#16
0
 private static async IAsyncEnumerable <object?> MapAsyncEnumerableInternal <T>(IAsyncEnumerable <T> asyncEnumerable)
 {
     if (asyncEnumerable is not null)
     {
         await foreach (var item in asyncEnumerable.ConfigureAwait(false))
         {
             yield return(item);
         }
     }
 }
示例#17
0
        public static async Task <TElement> First <TElement>(this IAsyncEnumerable <TElement> elements)
            where TElement : class, IAsyncListElement
        {
            await foreach (var element in elements.ConfigureAwait(false))
            {
                return(element);
            }

            throw new InvalidOperationException("Message List was empty, or timed out");
        }
示例#18
0
        public static async ValueTask <Dictionary <TKey, TValue> > ToDictionaryAsync <T, TKey, TValue>(this IAsyncEnumerable <T> source, Func <T, TKey> keySelector, Func <T, TValue> valueSelector)
        {
            var result = new Dictionary <TKey, TValue>();

            await foreach (var item in source.ConfigureAwait(false))
            {
                result.Add(keySelector(item), valueSelector(item));
            }
            return(result);
        }
示例#19
0
        public static async ValueTask <List <T> > ToListAsync <T>(this IAsyncEnumerable <T> source)
        {
            var list = new List <T>();

            await foreach (var item in source.ConfigureAwait(false))
            {
                list.Add(item);
            }
            return(list);
        }
示例#20
0
        public static async ValueTask <int> CountAsync <T>(this IAsyncEnumerable <T> source)
        {
            int count = 0;

            await foreach (var item in source.ConfigureAwait(false))
            {
                count++;
            }
            return(count);
        }
示例#21
0
        async static ValueTask <T[]> ToArrayAsync <T>(IAsyncEnumerable <T> source)
        {
            var list = new List <T>();

            await foreach (var item in source.ConfigureAwait(false))
            {
                list.Add(item);
            }
            return(list.ToArray());
        }
示例#22
0
        /// <inheritdoc />
        public async IAsyncEnumerable <T> Populate <T>(IAsyncEnumerable <T> entities, byte[] body)
        {
            var json = Encoding.UTF8.GetString(body);

            await foreach (var entity in entities.ConfigureAwait(false))
            {
                JsonConvert.PopulateObject(json, entity, SerializerSettings);
                yield return(entity);
            }
        }
示例#23
0
        public static async Task <ImmutableArray <T> > ToImmutableArrayAsync <T>(this IAsyncEnumerable <T> values)
        {
            using var _ = ArrayBuilder <T> .GetInstance(out var result);

            await foreach (var value in values.ConfigureAwait(false))
            {
                result.Add(value);
            }

            return(result.ToImmutable());
        }
示例#24
0
        public static async Task <List <T> > ToListAsync <T>(this IAsyncEnumerable <T> source)
        {
            var result = new List <T>();

            await foreach (var i in source.ConfigureAwait(false))
            {
                result.Add(i);
            }

            return(result);
        }
示例#25
0
 public static async IAsyncEnumerable <TValue> GetManyAsync <TKey, TValue>(
     this IAsyncKeyResolver <TKey, TValue> cache,
     IAsyncEnumerable <TKey> keys,
     [EnumeratorCancellation] CancellationToken cancellationToken = default)
     where TKey : notnull
 {
     await foreach (var key in keys.ConfigureAwait(false))
     {
         yield return(await cache.GetAsync(key, cancellationToken).ConfigureAwait(false));
     }
 }
示例#26
0
 public static async IAsyncEnumerable <T> TakeAsync <T>(this IAsyncEnumerable <T> source, int count)
 {
     await foreach (var item in source.ConfigureAwait(false))
     {
         if (count > 0)
         {
             count--;
             yield return(item);
         }
     }
 }
示例#27
0
        public static async Task <IList <T> > ToListAsync <T>(this IAsyncEnumerable <T> items)
        {
            List <T> output = new List <T>();

            await foreach (var item in items.ConfigureAwait(false))
            {
                output.Add(item);
            }

            return(output);
        }
示例#28
0
        internal static async Task <List <T> > ToListAsync <T>(this IAsyncEnumerable <T> items)
        {
            var results = new List <T>();

            await foreach (var item in items
                           .ConfigureAwait(false))
            {
                results.Add(item);
            }
            return(results);
        }
        public static async Task CopyToAsync(
            this IAsyncEnumerable <StreamPartition> partitions,
            Stream destination,
            bool async,
            CancellationToken cancellationToken)
        {
            var destinationOffset = destination.Position;

            await foreach (StreamPartition partition in partitions.ConfigureAwait(false))
            {
                if (async)
                {
                    await copyCore(partition).ConfigureAwait(false);
                }
                else
                {
                    copyCore(partition).EnsureCompleted();
                }
            }

            async Task copyCore(StreamPartition partition)
            {
                // if the destination is seekable, ensure we position it correctly,
                // else we trust the partitions are received in order and just write
                // blindly

                if (destination.CanSeek)
                {
                    destination.Position = partition.ParentPosition;
                }
                else
                {
                    Debug.Assert(
                        partition.ParentPosition == destination.Position - destinationOffset,
                        "Stream partitions received out of order for a non-seekable stream."
                        );
                }

                if (async)
                {
                    await
                    partition
                    .CopyToAsync(destination, Constants.DefaultBufferSize, cancellationToken)
                    .ConfigureAwait(false)
                    ;
                }
                else
                {
                    partition.CopyTo(destination, Constants.DefaultBufferSize);
                }

                partition.Dispose();
            }
        }
示例#30
0
        public static async Task <IEnumerable <T> > AsTask <T>(this IAsyncEnumerable <T> asyncEnumerable)
        {
            // TODO:
            var list = new List <T>();

            await foreach (var value in asyncEnumerable.ConfigureAwait(false))
            {
                list.Add(value);
            }
            return(list);
        }