/// <inheritdoc cref="DoWorkAsync{TResult}(IPriorityWorkQueue,IEnumerable{IAsyncWork{TResult}},int,CancellationToken,int,bool)" /> public static async IAsyncEnumerable <TResult> DoWorkAsync <TResult>(this IPriorityWorkQueue queue, IAsyncEnumerable <IAsyncWork <TResult> > works, int priority = 0, [EnumeratorCancellation] CancellationToken cancellation = default, int attemptsCount = 1) { _ = queue ?? throw new ArgumentNullException(nameof(queue)); var channel = Channel.CreateUnbounded <Task <TResult> >(new UnboundedChannelOptions { SingleReader = true, SingleWriter = true }); var reader = channel.Reader; var writer = channel.Writer; _ = Task.Run(async() => { try { await foreach (var work in works.WithCancellation(cancellation).ConfigureAwait(false)) { await writer.WriteAsync(queue.EnqueueAsyncWork(work, priority, cancellation, attemptsCount), cancellation) .ConfigureAwait(false); } } catch (OperationCanceledException ex) { await writer.WriteAsync(Task.FromCanceled <TResult>(ex.CancellationToken), CancellationToken.None).ConfigureAwait(false); } catch (Exception ex) { await writer.WriteAsync(Task.FromException <TResult>(ex), cancellation).ConfigureAwait(false); } finally { writer.Complete(); } }, cancellation); while (await reader.WaitToReadAsync(cancellation).ConfigureAwait(false)) { yield return(await(await reader.ReadAsync(cancellation).ConfigureAwait(false)).ConfigureAwait(false)); } }
/// <summary> Batch process works asynchronous with giver <paramref name="priority" /> </summary> /// <param name="queue"> Work Queue instance </param> /// <param name="works"> Works to process </param> /// <param name="cancellation"> Processing cancellation token </param> /// <param name="attemptsCount"> Retry on fail attempts count </param> /// <param name="priority"> Operation priority </param> /// <param name="enqueueAll"> Option to enqueue all data first </param> /// <typeparam name="TResult"> Processing result type </typeparam> /// <returns> Processing result task enumeration </returns> /// <exception cref="ArgumentNullException"> Thrown if <paramref name="queue" /> or <paramref name="works" /> is NULL </exception> public static async IAsyncEnumerable <TResult> DoWorkAsync <TResult>(this IPriorityWorkQueue queue, IEnumerable <IAsyncWork <TResult> > works, int priority = 0, [EnumeratorCancellation] CancellationToken cancellation = default, int attemptsCount = 1, bool enqueueAll = false) { _ = queue ?? throw new ArgumentNullException(nameof(queue)); var results = (works ?? throw new ArgumentNullException(nameof(works))).Select(work => queue.EnqueueAsyncWork(work, priority, cancellation, attemptsCount)); if (enqueueAll) { results = results.ToList(); } foreach (var result in results) { yield return(await result.ConfigureAwait(false)); } }