I have this straightforward loop that I'd like to write declaratively, using LINQ.
async Task<Foo> GetFooAsync(string fooId, CancellationToken cancellationToken = default(CancellationToken))
{
foreach (var source in FooSources)
{
var result = await source.GetFooAsync(fooId, cancellationToken).ConfigureAwait(continueOnCapturedContext: false);
if (result != null)
{
return result;
}
}
return null;
}
I wish for something that looks like:
return FooSources.Where(...).FirstOrDefault();
I'm stuck, especially on making LINQ and async
/await
work together.
Your options for async
LINQ are very limited. As the other answer pointed out, you can use async methods in Select
, but that's about it:
var tasks = FooSources.Select(source => source.GetFooAsync(fooId, cancellationToken));
This will get you a sequence of Task<Foo>
. You can then await for them all to complete:
var results = await Task.WhenAll(tasks);
Now you have an array of Foo
, which can be filtered:
return results.Where(foo => foo != null);
Note that this has very different semantics than your original code. Your original code will await
each source before starting the next; this answer will start all sources going, and then await
them all.
If you want foreach
semantics and need to await
inside the loop, then the correct solution is to use a foreach
loop containing an await
. There is no direct LINQ equivalent.
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