var items =
Enumerable.Range(1, 3)
.Select(n => Source(n, n % 2 is 0))
.Merge();
await foreach (var item in items)
Console.WriteLine(item);
async IAsyncEnumerable<int> Source(int n, bool fail = false)
{
await Task.Delay(TimeSpan.FromSeconds(n));
yield return n;
if (fail)
throw new();
}
When run, it will output:
1
2
System.ArgumentException: The tasks argument contains no tasks. (Parameter 'tasks')
at System.Threading.Tasks.Task.WhenAny[TTask](ReadOnlySpan`1 tasks)
at System.Threading.Tasks.Task.WhenAny[TTask](IEnumerable`1 tasks)
at System.Threading.Tasks.Task.WhenAny[TResult](IEnumerable`1 tasks)
at MoreLinq.Experimental.Async.ExperimentalEnumerable.<>c__DisplayClass1_0`1.<<Merge>g__Async|0>d.MoveNext()
--- End of stack trace from previous location ---
at MoreLinq.Experimental.Async.ExperimentalEnumerable.<>c__DisplayClass1_0`1.<<Merge>g__Async|0>d.System.Threading.Tasks.Sources.IValueTaskSource<System.Boolean>.GetResult(Int16 token)
at UserQuery.Main() in C:\Users\johndoe\AppData\Local\Temp\LINQPad8\_hiuxehhq\uljkai\LINQPadQuery:line 7
at UserQuery.Main() in C:\Users\johndoe\AppData\Local\Temp\LINQPad8\_hiuxehhq\uljkai\LINQPadQuery:line 7
It throws ArgumentException when it should have thrown Exception.
The problem seems to be due to the following clean-up loop, which can call Task.WhenAny with zero tasks:
Code to reproduce:
When run, it will output:
It throws
ArgumentException
when it should have thrownException
.The problem seems to be due to the following clean-up loop, which can call
Task.WhenAny
with zero tasks:https://github.com/morelinq/MoreLINQ/blob/0e154ef592f33ce0f6f3d534a9eedee273f0ce72/MoreLinq/Experimental/Async/Merge.cs#L204-L211