コード例 #1
0
        public static AsyncStream <TResult> ParallelizeStreamAsync <T, TResult>(this AsyncStream <T> source,
                                                                                Func <T, CancellationToken, Task <TResult> > actionAsync, ParallelizeOption option)
        {
            if (actionAsync == null)
            {
                throw new ArgumentNullException(nameof(actionAsync));
            }

            return(ParallelizeStreamInternalAsync(source, actionAsync, option));
        }
コード例 #2
0
        public static AsyncStream <T> ForEachAsync <T>(this AsyncStream <T> source, Func <StreamedValue <T>, CancellationToken, Task> action)
        {
            var channel = Channel.CreateUnbounded <StreamedValue <T> >(new UnboundedChannelOptions
            {
                SingleWriter = false,
                SingleReader = false
            });

            return(new AsyncStream <T>(channel, source.CancellationToken, async() =>
            {
                await ForeachInternalAsync(source, action, channel);
            }));
        }
コード例 #3
0
        public static async Task <ParallelizedSummary> GetExceptionsAsync <T>(this AsyncStream <T> source)
        {
            var exceptions = new ConcurrentBag <Exception>();

            await foreach (var sourceValue in source.ChannelReader.ReadAllAsync())
            {
                if (sourceValue.Status == ExecutionStatus.Faulted && sourceValue.Exception != null)
                {
                    exceptions.Add(sourceValue.Exception);
                }
            }
            return(new ParallelizedSummary(exceptions, source.CancellationToken.IsCancellationRequested));
        }
コード例 #4
0
 private static async Task CountInternalAsync <T>(AsyncStream <T> source, Counter localCounter, Channel <StreamedValue <T> > channel)
 {
     try
     {
         await foreach (var item in source.ChannelReader.ReadAllAsync(source.CancellationToken))
         {
             localCounter.Increment();
             await channel.Writer.WriteAsync(item, source.CancellationToken);
         }
     }
     finally
     {
         channel.Writer.Complete();
     }
 }
コード例 #5
0
        public static AsyncStream <T> CountAsync <T>(this AsyncStream <T> source, out Counter counter)
        {
            var localCounter = new Counter();

            counter = localCounter;
            var channel = Channel.CreateUnbounded <StreamedValue <T> >(new UnboundedChannelOptions
            {
                SingleWriter = false,
                SingleReader = false
            });

            return(new AsyncStream <T>(channel, source.CancellationToken, async() =>
            {
                await CountInternalAsync(source, localCounter, channel);
            }));
        }
コード例 #6
0
        private static async Task ForeachInternalAsync <T>(AsyncStream <T> source, Func <StreamedValue <T>, CancellationToken, Task> action, Channel <StreamedValue <T> > channel)
        {
            try
            {
                await foreach (var item in source.ChannelReader.ReadAllAsync(source.CancellationToken))
                {
                    await action(item, source.CancellationToken);

                    await channel.Writer.WriteAsync(item, source.CancellationToken);
                }
            }
            finally
            {
                channel.Writer.Complete();
            }
        }
コード例 #7
0
        private static Task ParallelizeCoreStreamAsync <T, TResult>(ParallelizeCore core,
                                                                    Func <T, CancellationToken, Task <TResult> > actionAsync,
                                                                    AsyncStream <T> source,
                                                                    ChannelWriter <StreamedValue <TResult> > resultsChannel,
                                                                    int index,
                                                                    ParallelMonitor <T> monitor)
        {
            return(Task.Run(async() =>
            {
                while (await source.ChannelReader.WaitToReadAsync()) //returns false when the channel is completed
                {
                    while (source.ChannelReader.TryRead(out StreamedValue <T> streamedValue))
                    {
                        if (streamedValue.Status != ExecutionStatus.Succeeded)
                        {
                            continue;
                        }

                        var item = streamedValue.Item;
                        monitor.SetActive(index, item);
                        if (core.IsLoopBreakRequested)
                        {
                            await YieldNotExecutedAsync(resultsChannel, default, item);
コード例 #8
0
        public static async Task <IReadOnlyCollection <T> > AsReadOnlyCollectionAsync <T>(this AsyncStream <T> source)
        {
            var items = new ConcurrentBag <T>();

            await foreach (var item in source.ChannelReader.ReadAllAsync(source.CancellationToken))
            {
                items.Add(item.Item);
            }
            return(items);
        }
コード例 #9
0
        private static AsyncStream <TResult> ParallelizeStreamInternalAsync <T, TResult>(this AsyncStream <T> source,
                                                                                         Func <T, CancellationToken, Task <TResult> > actionAsync, ParallelizeOption option)
        {
            var core    = new ParallelizeCore(source.CancellationToken, option);
            var monitor = new ParallelMonitor <T>(option.MaxDegreeOfParallelism);
            var channel = Channel.CreateUnbounded <StreamedValue <TResult> >();

            return(new AsyncStream <TResult>(channel, source.CancellationToken, async() =>
            {
                try
                {
                    using (core)
                    {
                        await Task.WhenAll(Enumerable.Range(0, option.MaxDegreeOfParallelism)
                                           .Select(i => ParallelizeCoreStreamAsync(core, actionAsync, source, channel, i, monitor)));
                    }
                }
                catch (Exception e)
                {
                    channel.Writer.Complete(e);
                    throw;
                }
                finally
                {
                    channel.Writer.Complete();
                }
                ThrowOnErrors(option, core);
            }));
        }