/// <inheritdoc /// cref="AccessAsync{TResource,TResult}(IPriorityAccessQueue{TResource},IEnumerable{IAccess{TResource,TResult}},int,CancellationToken,int,bool)" /> public static IAsyncEnumerable <TResult> AccessAsync <TResource, TResult>(this IEnumerable <IAccess <TResource, TResult> > accesses, IPriorityAccessQueue <TResource> accessQueue, CancellationToken cancellation = default, int attemptsCount = 1, int priority = 0, bool enqueueAll = false) where TResource : notnull => (accessQueue ?? throw new ArgumentNullException(nameof(accessQueue))).AccessAsync(accesses,
/// <inheritdoc /// cref="AccessAsync{TResource,TResult}(IPriorityAccessQueue{TResource},IEnumerable{IAsyncAccess{TResource,TResult}},int,CancellationToken,int,bool)" /> public static IAsyncEnumerable <TResult> AccessAsync <TResource, TResult>(this IAsyncEnumerable <IAsyncAccess <TResource, TResult> > accesses, IPriorityAccessQueue <TResource> accessQueue, int priority, CancellationToken cancellation = default, int attemptsCount = 1) where TResource : notnull => accessQueue.AccessAsync(accesses, priority, cancellation, attemptsCount);
/// <summary> Batch process access actions with giver <paramref name="priority" /> </summary> /// <param name="accessQueue"> Access Queue instance </param> /// <param name="accesses"> Access actions to process </param> /// <param name="priority"> Operation priority </param> /// <param name="cancellation"> Processing cancellation token </param> /// <param name="attemptsCount"> Retry on fail attempts count </param> /// <param name="enqueueAll"> Option to enqueue all data first </param> /// <typeparam name="TResource"> Shared resource type </typeparam> /// <typeparam name="TResult"> Processing result type </typeparam> /// <returns> Processing result task enumeration </returns> /// <exception cref="ArgumentNullException"> Thrown if <paramref name="accessQueue" /> or <paramref name="accesses" /> is NULL </exception> public static async IAsyncEnumerable <TResult> AccessAsync <TResource, TResult>(this IPriorityAccessQueue <TResource> accessQueue, IEnumerable <IAccess <TResource, TResult> > accesses, int priority = 0, [EnumeratorCancellation] CancellationToken cancellation = default, int attemptsCount = 1, bool enqueueAll = false) where TResource : notnull { _ = accessQueue ?? throw new ArgumentNullException(nameof(accessQueue)); var results = (accesses ?? throw new ArgumentNullException(nameof(accesses))).Select(access => accessQueue.EnqueueAccess(access, priority, cancellation, attemptsCount)); if (enqueueAll) { results = results.ToList(); } foreach (var result in results) { yield return(await result.ConfigureAwait(false)); } }
/// <inheritdoc /// cref="AccessAsync{TResource,TResult}(IPriorityAccessQueue{TResource},IEnumerable{IAsyncAccess{TResource,TResult}},int,CancellationToken,int,bool)" /> public static async IAsyncEnumerable <TResult> AccessAsync <TResource, TResult>(this IPriorityAccessQueue <TResource> accessQueue, IAsyncEnumerable <IAsyncAccess <TResource, TResult> > accesses, int priority, [EnumeratorCancellation] CancellationToken cancellation = default, int attemptsCount = 1) where TResource : notnull { _ = accessQueue ?? throw new ArgumentNullException(nameof(accessQueue)); 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 access in accesses.WithCancellation(cancellation).ConfigureAwait(false)) { await writer.WriteAsync(accessQueue.EnqueueAsyncAccess(access, 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)); } }