@@ -103,6 +103,20 @@ public int? StaticDegreeOfParallelism
103103 /// </summary>
104104 public int Count => _requestsChannel . Count ;
105105
106+ /// <summary>
107+ /// Represents a task that completes when all the requests currently present in the handler have finished processing.
108+ /// This task does not account for any requests that may be added to the handler after its creation.
109+ /// </summary>
110+ /// <remarks>
111+ /// <strong>Warning:</strong> This operation may block the handler for a period of time.
112+ /// </remarks>
113+ public Task CurrentTask => Task . WhenAll ( _requestsChannel . ToArray ( ) . Select ( requestPair => requestPair . Item . Task ) ) ;
114+
115+ /// <summary>
116+ /// Specifies a request that should be executed immediately after this request completes, bypassing the queue.
117+ /// </summary>
118+ IRequest ? IRequest . SubsequentRequest => null ;
119+
106120 /// <summary>
107121 /// Initializes a new instance of the <see cref="RequestHandler"/> class with a priority channel.
108122 /// If the priority count is zero, an exception is thrown; otherwise, a fixed-size priority channel is created.
@@ -285,11 +299,38 @@ private async Task HandleRequests(PriorityItem<IRequest> pair)
285299 await request . StartRequestAsync ( ) ;
286300
287301 if ( request . State is RequestState . Compleated or RequestState . Failed or RequestState . Cancelled )
302+ {
288303 request . Dispose ( ) ;
304+
305+ if ( request . SubsequentRequest != null )
306+ await SubsequentRequest ( request ) ;
307+ }
289308 else if ( request . State == RequestState . Idle )
290309 await _requestsChannel . Writer . WriteAsync ( pair ) ;
291310 }
292311
312+ /// <summary>
313+ /// Processes the subsequent request of the given request. Starts it if the current request completes,
314+ /// or disposes it and processes the chain if the current request fails or is canceled.
315+ /// </summary>
316+ /// <param name="request">The request to process.</param>
317+ /// <returns>A task representing the operation.</returns>
318+ private async Task SubsequentRequest ( IRequest request )
319+ {
320+ IRequest subRequest = request . SubsequentRequest ! ;
321+ if ( request . State == RequestState . Compleated )
322+ {
323+ if ( subRequest . State != RequestState . Running && subRequest . TrySetIdle ( ) )
324+ await HandleRequests ( new PriorityItem < IRequest > ( subRequest . Priority , subRequest ) ) ;
325+ }
326+ else
327+ {
328+ subRequest . Dispose ( ) ;
329+ if ( subRequest . SubsequentRequest != null )
330+ await SubsequentRequest ( subRequest . SubsequentRequest ) ;
331+ }
332+ }
333+
293334 /// <summary>
294335 /// Sets the priority for the <see cref="RequestContainer{TRequest}"/>.
295336 /// Not to the contained <see cref="IRequest"/> objects.
@@ -313,7 +354,7 @@ public void UpdateAutoParallelism()
313354 public bool TrySetIdle ( )
314355 {
315356 Pause ( ) ;
316- var requests = _requestsChannel . ToArray ( ) ;
357+ PriorityItem < IRequest > [ ] requests = _requestsChannel . ToArray ( ) ;
317358 foreach ( PriorityItem < IRequest > priorityItem in requests )
318359 _ = priorityItem . Item . TrySetIdle ( ) ;
319360 return requests . All ( x => x . Item . State == RequestState . Idle ) ;
@@ -339,7 +380,7 @@ public void Dispose()
339380 /// <returns>A string that represents the current state of the <see cref="RequestHandler"/>.</returns>
340381 public override string ToString ( )
341382 {
342- var sb = new StringBuilder ( ) ;
383+ StringBuilder sb = new ( ) ;
343384
344385 sb . AppendLine ( "RequestHandler State:" ) ;
345386 sb . AppendLine ( $ " Disposed: { _disposed } ") ;
@@ -369,21 +410,25 @@ public void Remove(params IRequest[] requests)
369410 if ( requests == null || requests . Length == 0 )
370411 throw new ArgumentNullException ( nameof ( requests ) , "Requests cannot be null or empty." ) ;
371412
372- foreach ( var request in requests )
413+ foreach ( IRequest request in requests )
373414 if ( ! _requestsChannel . TryRemove ( new ( request . Priority , request ) ) )
374415 throw new InvalidOperationException ( $ "Failed to remove request: { request } ") ;
375416 }
376417
377418 /// <summary>
378- /// Returns an enumerator that iterates through the collection of requests.
379- /// Blocks the Handler for a amout of time.
419+ /// Returns an enumerator that iterates through the collection of requests.
420+ /// <remarks>
421+ /// <strong>Warning:</strong> This operation may block the handler for a period of time.
422+ /// </remarks>
380423 /// </summary>
381- /// <returns>An enumerator that can be used to iterate through the collection.</returns>
424+ /// <returns>An enumerator that can be used to iterate through the collection of requests .</returns>
382425 public IEnumerator < IRequest > GetEnumerator ( ) => _requestsChannel . ToArray ( ) . Select ( pair => pair . Item ) . GetEnumerator ( ) ;
383426
384427 /// <summary>
385- /// Returns an enumerator that iterates through a collection.
386- /// Blocks the Handler for a amout of time.
428+ /// Returns an enumerator that iterates through the collection of requests.
429+ /// <remarks>
430+ /// <strong>Warning:</strong> This operation may block the handler for a period of time.
431+ /// </remarks>
387432 /// </summary>
388433 /// <returns>An <see cref="System.Collections.IEnumerator"/> object that can be used to iterate through the collection.</returns>
389434 System . Collections . IEnumerator System . Collections . IEnumerable . GetEnumerator ( ) => GetEnumerator ( ) ;
0 commit comments