Async lambda expression with await returns Task?

我与影子孤独终老i 提交于 2020-05-26 10:22:51

问题


I have the following code:

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

I would expect streams to be of type IEnumerable<Stream> but in fact it is of IEnumberable<Task<Stream>>, which is what I would've expected had I omitted the await keyword. The return type of OpenStreamForWriteAsync is Task<Stream> — surely awaiting it should produce a Stream?

So, why is the return await statement returning a Task?

Thanks for your help.


回答1:


All async methods return either void, Task, or Task<TResult>. The lambda is just an anonymous method, and thus that still applies. It's essentially the same as this named method:

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

In order to make it return a Stream it would need to be a blocking method, rather than an async method:

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

You probably don't want that.

You can turn your IEnumerable<Task<Stream>> into a Task<Stream[]> by using Task.WhenAll if that helps you:

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



回答2:


Wouldnt this be the best solution?

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


来源:https://stackoverflow.com/questions/13982195/async-lambda-expression-with-await-returns-task

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!