Short answer: you can't use an asynchronous yield statement.
But in most cases, you don't need to. Using LINQ you can aggregate all tasks before passing them into Task.WaitAll. I simplified your example to return an IEnumerable<int>, but this will work with every type.
public class Program
{
public static Task<int> X(int x)
{
return Task.FromResult(x);
}
public static async Task<IEnumerable<int>> GetYAsync(IEnumerable<int> infos)
{
var res = await Task.WhenAll(infos.Select(info => X(info)));
return res;
}
public static async void Main()
{
var test = await GetYAsync(new [] {1, 2, 3});
Console.WriteLine(test);
}
}
Your example has another error await new Y(...), a constructor cannot be asynchronous, therefore I replaced it with an asynchronous function. (As hinted in the comments, it is technically possible to create a custom awaitable type and create this type with new, although this is rarely used),
The example above uses infos.Select to create a list of pending tasks, returned by invoking the function X. This list of tasks will then be awaited and returned.
This workaround should fit most cases. Real asynchronous iterators, as for example in JavaScript, are not supported in .Net.
Update: This feature is currently suggested as a language proposal: Async Streams. So maybe we will see this in the future.
Update: If you need asynchronous iterators, there are a few options currently available:
- Reactive Stream, RX.Net, which provides you with asynchronous observable streams based on events.
- There are implementations of asynchronous iterators or asynchronous enumerables AsyncEnumerable or
.Net Async Enumerable
yieldis meant to be doing here. Andreturn awaitjust adds unnecessary layering if that's the onlyawaitin a method.Yalso appears to be some form of awaitable since you'reawaiting the result of constructing one. I really have no idea what you're trying to do here.