我有以下
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
,其中任何一个都不能转换为“FuncTask<T>
”。
一种方法是项目到
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);
这种方法的问题在于,您可能会不必要地处理所有项目。
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));