C# 将异步循环转换为LINQ查询
我有一个简单的循环,我想使用LINQ以声明方式编写它C# 将异步循环转换为LINQ查询,c#,linq,async-await,C#,Linq,Async Await,我有一个简单的循环,我想使用LINQ以声明方式编写它 async Task<Foo> GetFooAsync(string fooId, CancellationToken cancellationToken = default(CancellationToken)) { foreach (var source in FooSources) { var result = await source.GetFooAs
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;
}
我被卡住了,尤其是在使LINQ和
async
/wait
协同工作的问题上。您对async
LINQ的选择非常有限。正如另一个答案所指出的,您可以在Select
中使用异步方法,但仅此而已:
var tasks = FooSources.Select(source => source.GetFooAsync(fooId, cancellationToken));
这将为您提供一系列任务
。然后,您可以等待它们全部完成:
var results = await Task.WhenAll(tasks);
现在您有了一个Foo
数组,可以对其进行筛选:
return results.Where(foo => foo != null);
请注意,这与您的原始代码具有非常不同的语义。您的原始代码将在开始下一个源代码之前等待每个源代码;此答案将启动所有源,然后等待所有源
如果您想要
foreach
语义,并且需要在循环内await
,那么正确的解决方案是使用包含await
的foreach
循环。没有直接的LINQ等价物。您也可以在lambda中使用async:)安装resharper,您可以将这样的循环转换为lambdaexpression@FabianBigler:在回答中,让我们看看那会是什么样子。
return results.Where(foo => foo != null);