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)); }
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); })); }
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)); }
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(); } }
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); })); }
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(); } }
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);
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); }
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); })); }