Closed wbuck closed 3 years ago
The current OrderByCompletion
does immediately return a collection of tasks that would be completed in order, so it seems to do what you want already?
An async streams OrderByCompletion
would make sense if the number of source tasks were unknown. I'm not sure how useful that would be - it seems unusual to have an IAsyncEnumerable<Task<T>>
, which would be the input for that kind of operator.
would make sense if the number of source tasks were unknown.
That's exactly when it is useful. And concurrency limit. And results buffering. Of course, we can use Dataflow, but it can be easier
static async Task Main(string[] args)
{
IEnumerable<string> urls = ...; //infinite (or not. why not?)
await foreach (var downloadFileTask in urls.Select(DownloadAsync).ForEachAsync(concurrency: 3 ,capacity: 20))
{
...
}
}
private static Task<string> DownloadAsync(string url)...
It's trivial to do yourself:
public static async IAsyncEnumerable<T> ToAsCompletedAsyncEnumerable<T>(this IEnumerable<Task<T>> tasks)
{
foreach (var task in tasks.OrderByCompletion())
{
yield return await task.ConfigureAwait(false);
}
}
@Arithmomaniac
And block a thread from the threadpool to wait for the next task in foreach? what a waste. I would like something like this
@vitidev
Clearly I'm still rusty on how await
works; isn't the point that awaiting a task is effectively thread-free?
@Arithmomaniac
Clearly I'm still rusty on how await works;
It looks like I'm wrong. It seems I poor understand well how IAsyncEnumerable with yield return await
works
Closing this as OrderByCompletion
handles the common case (including IEnumerable<Task>
input).
For the dynamically-added case (IAsyncEnumerable<Task>
input), I would prefer operators (like "approximate order by completion") become a part of System.Linq.Async
rather than AsyncEx.
Hello Stephen, I was wondering if it would be possible to have the
OrderByCompletion
return anIAsyncEnumerable<T>
instead of aList<Task<T>>
(making it an async stream).await foreach ( var value in tasks.OrderByCompletion( token ) ) { }
I'm unsure if this would be at all possible and I haven't really thought through the implications of this. Currently to achieve what I want I've written some ugly code using the ye olde
Task.WhenAny
in a loop and yield returning the result from the completedTask
. I know this isn't the most efficient way of doing it. I'm just curious if something like this would be possible.By the way, really enjoying the new book.