-
Notifications
You must be signed in to change notification settings - Fork 5.2k
Description
Description
The WhenAll awaiter has always thrown the exception from the first faulting task only, where 'first' refers to the order within the collection of tasks passed to WhenAll, rather than to the order in which the exceptions were thrown.
This changes in .NET 8, and it only changes for nongeneric Task.WhenAll. Generic Task.WhenAll retains the behavior that WhenAll has always had.
There is no mention of this in https://learn.microsoft.com/en-us/dotnet/core/compatibility/8.0#core-net-libraries.
Was this intentional, or perhaps an accidental side effect during #88154 or other recent performance improvements? /cc @stephentoub
Reproduction Steps
var ex1 = new Exception();
var ex2 = new Exception();
try
{
var source1 = new TaskCompletionSource<object>();
var source2 = new TaskCompletionSource<object>();
// If the (Task) cast is removed, the behavior changes back to .NET 7 behavior.
var whenAllTask = Task.WhenAll((Task)source1.Task, source2.Task);
source2.SetException(ex2);
source1.SetException(ex1);
await whenAllTask;
}
catch (Exception ex)
{
Console.WriteLine(ReferenceEquals(ex, ex1)); // False on .NET 8, true on .NET 7.
}
Expected behavior
The exception thrown during the await continuing to be the exception from the first task, as in all prior versions of .NET.
Actual behavior
The exception thrown during the await is the exception from the last task.
Regression?
No response
Known Workarounds
No response
Configuration
Used .NET SDK 8.0.100-rc.2.23502.2.
Other information
No response