C #은 Enumerable에서 Bool을 반환하는 비동기 람다 식을 사용합니다.

Sep 28 2020

다음과 같은 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 비동기 람다 식을 'Func <string, bool>'대리자 형식으로 변환 할 수 없습니다. 비동기 람다 식은 void, Task 또는 Task를 반환 할 수 있으며 이들 중 아무것도 'Func <string, bool>'로 변환 할 수 없습니다.

답변

4 00110001 Sep 28 2020 at 15:07

한 가지 방법은하는 것 프로젝트 에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 PanagiotisKanavos Sep 28 2020 at 15:26

Michael Randall의 대답은 올바른 논리적 결과를 생성하지만 두 경우 모두에 대한 첫 번째 false결과 All또는에 대한 첫 번째 결과에 의해 평가가 단락 될 수 있지만 모든 정책을 평가해야 true합니다 Any.

이는 작업을로 변환하고 System.Linq.Async를IAsyncenumerable<T> 사용하여 피할 수 있습니다 .

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

var result1 = await (IsAndPolicy 
                       ? resultTasks.AllAsync(x => x)                
                       : resultTasks.AnyAsync(x => x));