在 Enumerable.All 扩展中使用带有返回 bool 的异步 lambda 表达式

问题描述 投票:0回答:2

我有以下

async
方法

private async Task<bool> HasPolicy(AuthorizationFilterContext context, string policy)
{
    var authorized = await _authorization.AuthorizeAsync(context.HttpContext.User, policy);
    return authorized.Succeeded;
}

我想在

Enumerable.All
Enumerable.Any
扩展中使用它

var result1 = IsAndPolicy
    ? policys.All(async x => await HasPolicy(context, x))
    : policys.Any(async x => await HasPolicy(context, x));

但是上面的代码出现以下错误

错误 CS4010 无法将异步 lambda 表达式转换为委托类型“Func”。异步 lambda 表达式可能返回

void
Task
Task<T>
,其中任何一个都不能转换为“Func”。

c# lambda async-await
2个回答
4
投票

一种方法是项目

IEnumerable<Task<bool>>

var results = await Task.WhenAll(policys.Select(x => HasPolicy(context, x)));

var result1 = IsAndPolicy 
   ? results.All(x => x)                
   : results.Any(x => x);

这种方法的问题在于,您可能会不必要地处理所有项目。


2
投票

Michael Randall 的答案产生了正确的逻辑结果,但必须评估所有策略,即使在这两种情况下,评估都可以通过

false
的第一个
All
结果或
true
 结果短路Any

可以通过将任务转换为

IAsyncenumerable<T>
并使用 System.Linq.Async 来避免这种情况:

var resultTasks=policies.ToAsyncEnumerable()
                        .Select(async x => await HasPolicy(context, x));

var result1 = await (IsAndPolicy 
                       ? resultTasks.AllAsync(x => x)                
                       : resultTasks.AnyAsync(x => x));
© www.soinside.com 2019 - 2024. All rights reserved.