2012-12-20 2 views
11

나는 다음과 같은 코드가 있습니다비동기식 람다식이 대기 태스크와 함께 반환됩니까?

  // Get all of the files from the local storage directory. 
     var files = await folder.GetFilesAsync(); 

     // Map each file to a stream corresponding to that file. 
     var streams = files.Select(async f => { return await f.OpenStreamForWriteAsync(); }); 

내가 streams 유형 IEnumerable<Stream> 될 기대를하지만, 사실 그것은 내가 await를 키워드를 생략했다 내가 기대 한 것이 무엇 인 IEnumberable<Task<Stream>>이다. 반환 유형 OpenStreamForWriteAsyncTask<Stream>입니다. 확실히 기다리면 Stream이 생성됩니까?

그렇다면 반환 대기 명세서가 작업을 반환하는 이유는 무엇입니까?

도움 주셔서 감사합니다.

+2

비동기 메소드는 항상 '작업 '또는 '작업'을 반환합니다. Select 자체는 반환 유형에 대해 신경 쓰지 않습니다. 따라서 선택 람다가 비동기이기 때문에 열거 할 수있는 작업을 계획합니다. 컬렉션을 반복하고 스트림을 기다릴 수 있습니다. – vcsjones

+0

음, 여기서 "비동기 무효화"방법을 쓸 수 있습니다. 어떻게 수정합니까? –

+0

좋아요. 시도해 보겠습니다. –

답변

9

, Task 또는 Task<TResult> 중 하나를 반환합니다. 람다는 익명의 방법 일 뿐이므로 여전히 적용됩니다. 그것은 본질적으로이라는 방법과 동일합니다 :

private static async Task<Stream> Foo(TypeGOesHere f) 
{ 
    return await f.OpenStreamForWriteAsync(); 
} 

그것은 Stream 그것을 차단 방법보다는 비동기 방법이 될 필요가 복귀하기 위해서는 :

private static Stream Foo(TypeGOesHere f) 
{ 
    return f.OpenStreamForWriteAsync().Result; 
} 

당신은 아마 '돈 그걸 원해.

당신은 회전 할 수 IEnumerable<Task<Stream>>Task<Stream[]>에 그게 당신을 도움이된다면 Task.WhenAll를 사용하여 :

Task<Stream[]> resultTask = Task.WhenAll(streams); 
+0

아니면, 더 좋은 방법은 비동기 메서드를 닫고'var streams = files.Select (await f.OpenStreamForWriteAsync()); '를 사용하는 것입니다. 비동기 한정자가 있어야하는 것은 람다가 아닙니다. – shipr

0

가 wouldnt는 이것이 최선의 해결책이 될?

 // Get all of the files from the local storage directory. 
    var files = await folder.GetFilesAsync(); 

    // Map each file to a stream corresponding to that file and await the Task that waits for all tasks to complete? maybe thats whats being implied above... 
    var streams = await Task.WhenAll(files.Select(async f => { return await f.OpenStreamForWriteAsync(); }));