Skip to content

Simply the concurrency limit with task #53709

@WeihanLi

Description

@WeihanLi

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions