2012-12-20 53 views
11

Tôi có đoạn mã sau:Biểu thức async lambda với chờ đợi trả về Nhiệm vụ?

  // 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(); }); 

Tôi mong chờ streams là loại IEnumerable<Stream> nhưng trên thực tế nó là của IEnumberable<Task<Stream>>, đó là những gì tôi sẽ đã mong đợi tôi đã bỏ qua các từ khóa đang chờ đợi. Kiểu trả về của OpenStreamForWriteAsyncTask<Stream> - chắc chắn đang chờ nó sẽ tạo ra một Stream?

Vì vậy, tại sao câu trả về đang chờ trả lại trả lại một Tác vụ?

Cảm ơn sự giúp đỡ của bạn.

+2

phương thức không đồng bộ luôn trả về 'Tác vụ ' hoặc 'Tác vụ'. Chọn chính nó không quan tâm đến kiểu trả về. Vì vậy, nó dự án một nhiệm vụ enumerable bởi vì lambda chọn của bạn là không đồng bộ. Bạn có thể lặp qua bộ sưu tập của mình và chờ luồng. – vcsjones

+0

Vâng, người ta có thể viết một "async void" phương pháp, đó là những gì tôi cho là đã xảy ra ở đây. Làm cách nào để khắc phục sự cố? –

+0

OK Tôi sẽ thử điều đó. –

Trả lời

9

Tất cả phương thức async trả lại void, Task hoặc Task<TResult>. Lambda chỉ là một phương thức nặc danh, và do đó vẫn áp dụng. Đó là cơ bản giống như phương thức có tên này:

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

Để làm cho nó trở lại một Stream nó sẽ cần phải là một phương pháp ngăn chặn, chứ không phải là một phương pháp async:

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

Có thể bạn don' Tôi muốn điều đó.

Bạn có thể bật bạn IEnumerable<Task<Stream>> thành một Task<Stream[]> bằng cách sử dụng Task.WhenAll nếu điều đó giúp bạn:

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

Hoặc, tốt hơn, làm cho phương thức kèm theo không đồng bộ và sử dụng 'var streams = files.Select (await f.OpenStreamForWriteAsync());'. Nó không phải là lambda cần phải có công cụ sửa đổi không đồng bộ. – shipr

0

wouldnt này là giải pháp tốt nhất?

 // 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(); })); 
Các vấn đề liên quan