Правильный синтаксис:
await foreach(var filePath from service.GetFilePathsFromRelativePathAsync(relativePath))
{
....
}
IAsyncEnumerable
используется для возврата потока элементов, которые могут обрабатываться индивидуально. Вот почему эта функция на самом деле называется asyn c streams , что вызывает путаницу
Преобразование в задачу >
Лучшим решением было бы не преобразовать, но изменить подпись на IEnumerable<FileUpload>
и вернуть новые FileUpload
экземпляры, как только они будут созданы:
private async IAsyncEnumerable<FileUpload> GetFileUploadsAsync(string relativePath)
{
await foreach(var filePath from service.GetFilePathsFromRelativePathAsync(relativePath))
{
var upload = new FileUpload(filePath);
yield return upload;
}
}
You Можно также собрать все результаты, сохранить их в списке и вернуть их, например, с помощью метода расширения ToListAsync
:
public static async Task<List<T>> ToListAsync<T>(this IAsyncEnumerable<T> source, CancellationToken cancellationToken=default)
{
var list=new List<T>();
await foreach (var item in source.WithCancellation(cancellationToken).ConfigureAwait(false))
{
list.Add(item);
}
return list;
}
Лучший код - это код, который вы не пишете. Проект System.Linq.Asyn c предоставляет операторы LINQ для IAsyncEnumerable, включая ToList .
Код очень прост, но включает в себя несколько оптимизаций, например, использование ValueTask
вместо Task
и специальную обработку данных, поступающих от других операторов, таких как GroupBy и Reverse, которые должны потреблять все IAsyncEnumerable
прежде чем производить свою продукцию.