2013-05-31 5 views
5

나는 LINQ를 사용하여 선언적으로 작성하고자하는이 간단한 루프를 사용합니다. 특히 함께 LINQ 및 async/await 작품을 만들기에, 나는 붙어비동기 루프를 LINQ 쿼리로 변환

return FooSources.Where(...).FirstOrDefault(); 

:

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; 
    } 

나는처럼 보이는 뭔가를 바랍니다.

+0

비동기를 람다에서도 사용할 수 있습니다. –

+0

resharper를 설치하면 람다 식 –

+0

으로 변환 할 수 있습니다. @FabianBigler : 답안에서 어떻게 보이는지 보여주십시오. –

답변

13

async LINQ에 대한 옵션은 매우 제한되어 있습니다. 다른 답변이 지적한 것처럼, 당신은 Select에서 비동기 방법을 사용할 수 있지만 그게 관하여 :

var tasks = FooSources.Select(source => source.GetFooAsync(fooId, cancellationToken)); 

이 당신에게 Task<Foo>의 순서를 얻을 것이다. 그들 모두가 완료 될 때까지 그런 다음 기다리고 있습니다 :이 원래 코드보다 매우 다른 의미를 가지고

return results.Where(foo => foo != null); 

참고 :

var results = await Task.WhenAll(tasks); 

이제 필터링 할 수 있습니다 Foo의 배열을 가지고있다. 다음 코드를 시작하기 전에 원본 코드가 await 개입니다. 이 대답은 모든 소스가 시작될 것이고, 그 다음에 모두 await입니다. 당신이 foreach 의미를 원하는 루프 내부 await해야하는 경우

는 다음 올바른 솔루션은 await를 포함하는 foreach 루프를 사용하는 것입니다. 직접적인 LINQ는 없습니다.