2012-12-20 99 views
11

我有以下代碼:具有await返回任務的異步lambda表達式?

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

我希望streamsIEnumerable<Stream>型的,但實際上它是IEnumberable<Task<Stream>>,這是我會一直期待有我省略了的await關鍵字。 OpenStreamForWriteAsync的返回類型是Task<Stream> - 肯定等待它應該產生一個Stream

那麼,爲什麼返回等待語句返回一個任務?

感謝您的幫助。

+2

異步方法總是返回'任務'或'任務'。選擇本身並不關心返回類型。因此,它會投射一個可枚舉的Task,因爲您選擇的lambda是異步的。你可以遍歷你的集合並等待Stream。 – vcsjones

+0

那麼,人們可以寫一個「異步無效」的方法,這是我推測在這裏發生的。 我該如何解決? –

+0

好的,我會嘗試。 –

回答

9

全部async方法返回void,TaskTask<TResult>。 lambda只是一個匿名方法,因此仍然適用。它本質上是相同的,因爲這命名的方法:

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

爲了使其返回Stream這將需要一個阻塞方法,而不是異步方法:

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

你可能穿上」我想要那個。

您可以打開使用Task.WhenAll如果幫助您將IEnumerable<Task<Stream>>Task<Stream[]>

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

或者,更好的是,使封閉的方法異步並使用'var streams = files.Select(等待f.OpenStreamForWriteAsync());'。這不是需要具有異步修改器的lambda。 – shipr

0

難道不這是最好的解決辦法?

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