Let's say I have a sequence of integers I obtain asynchronously.
async Task<int> GetI(int i){
return await Task.Delay(1000).ContinueWith(x => i);
}
I want to create a generator over that sequence, if the sequence was synchronous I'd do:
IEnumerable<int> Method()
{
for (var i = 0; i < 100; i++)
{
yield return GetI(i); // won't work, since getI returns a task
}
}
So, I figured the analogy is making the generator async and yielding from it:
async Task<IEnumerable<int>> Method()
{
for (var i = 0; i < 100; i++)
{
yield return await Task.Delay(1000).ContinueWith(x => i);
}
}
This won't work, since a method with yield
must return an IEnumerable
of something, the alternative, which makes more sense is IEnumerable<Task<int>>
but that won't compile since async
methods must return Task
s or void.
Now, I realize I can simply remove the await and return an IEnumerable<Task<int>>
but that won't help me since the iteration will keep asking for data before any of it is ready, so it doesn't solve my issue.
- Is there any way to nicely mix enumerables and tasks with the nice sugar the language gives me with await and yield?
- Is there any way to nicely consume it?
(From searching online, I suspect the answer to the first question is false and the second one is an observer/observable, but I couldn't find any canonical reference and I'm interested in the best way to implement this pattern in C#)
See Question&Answers more detail:
os 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…