I have an async predicate method like this:
private async Task<bool> MeetsCriteria(Uri address) { //Do something involving awaiting an HTTP request. }
Say I have a collection of Uri
s:
var addresses = new[] { new Uri("http://www.google.com/"), new Uri("http://www.stackoverflow.com/") //etc. };
I want to filter addresses
using MeetsCriteria
. I want to do this asynchronously; I want multiple calls to the predicate to run asynchronously, and I want to then wait for all of them to complete and produce the filtered result set. Unfortunately, LINQ doesn't appear to support asynchronous predicates, so something like this doesn't work:
var filteredAddresses = addresses.Where(MeetsCriteria);
Is there a similarly convenient way to do this?
Asynchronous operations in parallelThe method async. parallel() is used to run multiple asynchronous operations in parallel.
It's usually wrong to provide an async implementation (or override) of a void-returning method on an interface (or base class). Some events also assume that their handlers are complete when they return.
The async and await keywords don't cause additional threads to be created. Async methods don't require multithreading because an async method doesn't run on its own thread. The method runs on the current synchronization context and uses time on the thread only when the method is active.
No, it does not. It MAY start another thread internally and return that task, but the general idea is that it does not run on any thread.
I think one of the reasons nothing like this is in the framework is that there is lots of possible variations and each choice will be the right one under certain circumstances:
Task<IEnumerable<T>>
to something else.)You said you want the predicates to execute in parallel. In that case, the simplest choice is to execute them all at once and return them in the order of completion:
static async Task<IEnumerable<T>> Where<T>( this IEnumerable<T> source, Func<T, Task<bool>> predicate) { var results = new ConcurrentQueue<T>(); var tasks = source.Select( async x => { if (await predicate(x)) results.Enqueue(x); }); await Task.WhenAll(tasks); return results; }
You could then use it like this:
var filteredAddresses = await addresses.Where(MeetsCriteria);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With