C # use la expresión lambda asíncrona con return bool en la extensión Enumerable.All
Tengo el siguiente asyncmétodo
private async Task<bool> HasPolicy(AuthorizationFilterContext context, string policy)
{
var authorized = await _authorization.AuthorizeAsync(context.HttpContext.User, policy);
return authorized.Succeeded;
}
Me gustaría usarlo en Enumerable.Ally Enumerable.Anyextensión
var result1 = IsAndPolicy
? policys.All(async x => await HasPolicy(context, x))
: policys.Any(async x => await HasPolicy(context, x));
Pero el código anterior obtiene el siguiente error
Error CS4010 No se puede convertir la expresión lambda asíncrona al tipo de delegado 'Func <string, bool>'. Una expresión lambda asíncrona puede devolver void, Task o Task, ninguno de los cuales es convertible a 'Func <string, bool>'.
Respuestas
Un enfoque sería proyectar a unIEnumerable<Task<bool>>
var results = await Task.WhenAll(policys.Select(x => HasPolicy(context, x)));
var result1 = IsAndPolicy
? results.All(x => x)
: results.Any(x => x);
El problema con este enfoque es que está procesando todos los elementos potencialmente innecesariamente.
La respuesta de Michael Randall produce el resultado lógico correcto pero tiene que evaluar todas las políticas, aunque en ambos casos la evaluación puede tener un cortocircuito, por el primer falseresultado para Allo el primer trueresultado para Any.
Esto se puede evitar convirtiendo las tareas a IAsyncenumerable<T>y usando 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));