-
Notifications
You must be signed in to change notification settings - Fork 4.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[API Proposal]: LINQ terminator .WhenAll() wrapping Task.WhenAll #107706
Comments
Tagging subscribers to this area: @dotnet/area-system-linq |
This doesn't really belong to LINQ. LINQ provides methods for collections of every type, not a particular type. The proposal is about creating simple wrappers of existing methods to satisfy certain language feature. Generally we won't do this as it's very simple for users to create their own. In other languages like F#, you can use |
Tagging subscribers to this area: @dotnet/area-system-threading-tasks |
There is precedent in us retroactively marking static methods as extension methods as long as their signature permits it. We could conceivably do that with the @stephentoub @terrajobst thoughts? |
Aren't extension methods only allowed inside static classes? |
FWIW this functionality already exists in await allThePeople
+ .ToAsyncEnumerable()
.Where(person => person.Labels.Contains(label))
.Where(person => person != caller)
- .Select(person => MessagePersonAsync(person, message))
- .WhenAll();
+ .ForEachAwaitAsync(person => MessagePersonAsync(person, message)); |
Note: this currently isn't allowed by C# language, which requires extension methods be defined in static types. |
Ah yes, good point. I don't think this change would be viable today. |
My gut reaction is that it feels niche and doesn't really add much syntactic sugar over the "ordinary way": public async Task SpreadTheWordAsync(Person caller, string message, string label)
{
await Task.WhenAll(
allThePeople
.Where(person => person.Labels.Contains(label))
.Where(person => person != caller)
.Select(person => MessagePersonAsync(person, message))
);
await MessagePersonAsync(caller, "The word has been spread");
} Now, this would be a lot more compelling if we extended Linq-style operators for public async Task SpreadTheWordAsync(Person caller, string message, string label)
{
await allThePeople
.Where(person => person.Labels.Contains(label))
.Where(person => person != caller)
.Select(person => MessagePersonAsync(person, message))
.ToAsyncEnumerable()
.WhenAll();
await MessagePersonAsync(caller, "The word has been spread");
} |
Agreed. I suppose we can close this in favor of #79782. |
Note that this is already achievable today: public static TaskAwaiter GetAwaiter(this IEnumerable<Task> tasks) => Task.WhenAll(tasks).GetAwaiter();
public static TaskAwaiter<T[]> GetAwaiter<T>(this IEnumerable<Task<T>> tasks) => Task.WhenAll(tasks).GetAwaiter(); With extension |
Background and motivation
This would support the fluent API of LINQ and avoid having to wrap a LINQ stack or its return value in a
Task.WhenAll()
call.API Proposal
API Usage
Alternative Designs
The
await
keyword could accept an IEnumerable instead.Risks
People might have already built this on their own.
The text was updated successfully, but these errors were encountered: