示例#1
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);
            }));
        }
示例#2
0
        private static void ThrowOnErrors(ParallelizeOption option, ParallelizeCore core)
        {
            if (option.FailMode != Fail.Default)
            {
                return;
            }

            if (core.IsFaulted)
            {
                if (core.Exceptions.Count() == 1)
                {
                    throw core.Exceptions.First();
                }

                throw new AggregateException(core.Exceptions);
            }

            if (core.IsCanceled)
            {
                throw new TaskCanceledException();
            }
        }
示例#3
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);