Background and Motivation
Currently, if we need to limit the concurrency, it may be a little hard to implement(maybe there's something I missed)
When we use Parallel, we could use MaxDegreeOfParallelism to limit the max concurrency, if we could add something like that to Task.WhenAll and Task.WhenAny method
When I use Task.WhenAll, I usually use a SemephoreSlim to limit the concurrency like follows:
var nums = Enmuerable.Range(1, 1000);
using var semaphore = new SemaphoreSlim(1, 50);
var result = await Task.WhenAll(
nums
.Select(async x =>
{
try
{
await semaphore.WaitAsync();
return await GetDetail(x);
}
finally
{
semaphore.Release();
}
})
).ToArray());
I think it's maybe a common requirement, hope there's a simple API to implement this.
Proposed API
namespace System.Threading.Tasks
{
public class Task{
+ public static Task WhenAll(IEnumerable<Task> tasks, int maxDegreeOfParallelism);
+ public static Task<TResult[]> WhenAll<TResult>(IEnumerable<Task<TResult>> tasks, int maxDegreeOfParallelism);
+ public static Task<Task> WhenAny(IEnumerable<Task> tasks, int maxDegreeOfParallelism);
+ public static Task<Task<TResult>> WhenAny<TResult>(IEnumerable<Task<TResult>> tasks, int maxDegreeOfParallelism);
}
Usage Examples
var nums = Enmuerable.Range(1, 1000);
await Task.WhenAll(nums.Select(async n => {
// async code block
}), 50);
Risks
Maybe there's something I missed.
Background and Motivation
Currently, if we need to limit the concurrency, it may be a little hard to implement(maybe there's something I missed)
When we use Parallel, we could use
MaxDegreeOfParallelismto limit the max concurrency, if we could add something like that toTask.WhenAllandTask.WhenAnymethodWhen I use
Task.WhenAll, I usually use aSemephoreSlimto limit the concurrency like follows:I think it's maybe a common requirement, hope there's a simple API to implement this.
Proposed API
namespace System.Threading.Tasks { public class Task{ + public static Task WhenAll(IEnumerable<Task> tasks, int maxDegreeOfParallelism); + public static Task<TResult[]> WhenAll<TResult>(IEnumerable<Task<TResult>> tasks, int maxDegreeOfParallelism); + public static Task<Task> WhenAny(IEnumerable<Task> tasks, int maxDegreeOfParallelism); + public static Task<Task<TResult>> WhenAny<TResult>(IEnumerable<Task<TResult>> tasks, int maxDegreeOfParallelism); }Usage Examples
Risks
Maybe there's something I missed.