Reputation: 325
I am trying to you use yield and return a result from converting X into Y in an async task. But, I am getting an error on select. The error is:
Error CS1942 The type of the expression in the select clause is incorrect. Type inference failed in the call to 'Select'.
public async Task<Result<dynamic>> GetYAsync(IEnumerable<X> infos)
{
return Task.WhenAll(from info in infos.ToArray() select async ()=>
{
yield return await new Y(info.Id, "Start");
});
}
Upvotes: 4
Views: 8103
Reputation: 1992
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:
Upvotes: 6
Reputation: 62157
You do not. Async Enum support (and yield is there to implement enumerable) comes with C# 8 some point in 2019 as it looks. So, for now the answer is simply that you do not.
The reason you get the error is that you can also not returna Result. Yield (return) is specific to implementing enumerations. Your method signature does not match.
Upvotes: 3