ExperimentalEnumerableAwaitT, TResult Method (IEnumerableT, FuncT, CancellationToken, TaskTResult)
public static IAwaitQuery<TResult> Await<T, TResult>( this IEnumerable<T> source, Func<T, CancellationToken, Task<TResult>> evaluator )
<ExtensionAttribute> Public Shared Function Await(Of T, TResult) ( source As IEnumerable(Of T), evaluator As Func(Of T, CancellationToken, Task(Of TResult)) ) As IAwaitQuery(Of TResult)
public: [ExtensionAttribute] generic<typename T, typename TResult> static IAwaitQuery<TResult>^ Await( IEnumerable<T>^ source, Func<T, CancellationToken, Task<TResult>^>^ evaluator )
[<ExtensionAttribute>] static member Await : source : IEnumerable<'T> * evaluator : Func<'T, CancellationToken, Task<'TResult>> -> IAwaitQuery<'TResult>
This method uses deferred execution semantics. The results are yielded as each asynchronous evaluation completes and, by default, not guaranteed to be based on the source sequence order. If order is important, compose further with AsOrderedT(IAwaitQueryT).
This method starts a new task where the asynchronous evaluations take place and awaited. If the resulting sequence is partially consumed then there's a good chance that some projection work will be wasted and a cooperative effort is done that depends on the evaluator function (via a CancellationToken as its second argument) to cancel those in flight.
The evaluator function should be designed to be thread-agnostic.
The task returned by evaluator should be started when the function is called (and not just a mere projection) otherwise changing concurrency options via AsSequentialT(IAwaitQueryT), MaxConcurrencyT(IAwaitQueryT, Int32) or UnboundedConcurrencyT(IAwaitQueryT) will only change how many tasks are awaited at any given moment, not how many will be kept in flight.