Асинхронное выражение 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(); });
Я бы ожидал, что streams
будет иметь тип IEnumerable<Stream>
, но на самом деле он имеет значение IEnumberable<Task<Stream>>
, что я и ожидал, если бы я опустил ключевое слово ожидания. Возвращаемый тип OpenStreamForWriteAsync
равен Task<Stream>
- наверняка ожидая, что он должен создать Stream
?
Итак, почему оператор return return возвращает задачу?
Спасибо за вашу помощь.
Ответы
Ответ 1
Все методы async
возвращают либо void
, Task
, либо Task<TResult>
. Лямбда - это просто анонимный метод, и, таким образом, он все еще применяется. Это по сути то же, что и этот метод:
private static async Task<Stream> Foo(TypeGOesHere f )
{
return await f.OpenStreamForWriteAsync();
}
Чтобы вернуть значение Stream
, это должен быть метод блокировки, а не метод async:
private static Stream Foo(TypeGOesHere f )
{
return f.OpenStreamForWriteAsync().Result;
}
Вероятно, вы этого не хотите.
Вы можете превратить IEnumerable<Task<Stream>>
в Task<Stream[]>
с помощью Task.WhenAll
, если это поможет вам:
Task<Stream[]> resultTask = Task.WhenAll(streams);
Ответ 2
Разве это не лучшее решение?
// 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(); }));