Skip to content

[API Proposal]: Making "Process asynchronous tasks as they complete" easy by using IAsyncEnumerable  #61959

Closed
@Vijay-Nirmal

Description

@Vijay-Nirmal

EDITED on 1/23/2024 by @stephentoub:

namespace System.Threading.Tasks;

public class Task
{
+   public static IAsyncEnumerable<Task> WhenEach(params Task[] tasks);
+   public static IAsyncEnumerable<Task> WhenEach(params ReadOnlySpan<Task> tasks); // params when possible
+   public static IAsyncEnumerable<Task> WhenEach(IEnumerable<Task> tasks);

+   public static IAsyncEnumerable<Task<TResult>> WhenEach(params Task<TResult>[] tasks); // params for now; move it to ReadOnlySpan overload when that syntax is possible
+   public static IAsyncEnumerable<Task<TResult>> WhenEach(params ReadOnlySpan<Task<TResult>> tasks); // params when possible
+   public static IAsyncEnumerable<Task<TResult>> WhenEach(IEnumerable<Task<TResult>> tasks);
}

Background and motivation

Currently, if we need to "Process asynchronous tasks as they complete" then we need to write lots of unnecessary codes and its not straight forward, something like below.

// Using currently available APIs
List<Task<int>> downloadTasks = downloadTasksQuery.ToList();
while (downloadTasks.Any())
{
    Task<int> finishedTask = await Task.WhenAny(downloadTasks);
    downloadTasks.Remove(finishedTask);
    Process(await finishedTask);
}

API Proposal

namespace System.Threading.Tasks
{
    public class Task : IAsyncResult, IDisposable
    {
        public static IAsyncEnumerable<Task> WhenEach(params Task[] tasks);  // Please change the name, if needed
        public static IAsyncEnumerable<Task> WhenEach(IEnumerable<Task> tasks);
        public static IAsyncEnumerable<Task<TResult>> WhenEach(params Task<TResult>[] tasks); 
        public static IAsyncEnumerable<Task<TResult>> WhenEach(IEnumerable<Task<TResult>> tasks);
    }
}

API Usage

// Using newly created APIs
await foreach (var finishedTask in Task.WhenEach(downloadTasksQuery))
{
    Process(await finishedTask);
}

Alternative Designs

No response

Risks

No response

Updates

(Others can edit this section and add more info)

Metadata

Metadata

Assignees

Labels

api-approvedAPI was approved in API review, it can be implementedarea-System.Threading.Tasksin-prThere is an active PR which will close this issue when it is merged

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions