Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 将异步循环转换为LINQ查询_C#_Linq_Async Await - Fatal编程技术网

C# 将异步循环转换为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

我有一个简单的循环,我想使用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;
    }

我被卡住了,尤其是在使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);