正确的语法是:
await foreach(var filePath in service.GetFilePathsFromRelativePathAsync(relativePath))
{
....
}
AnIAsyncEnumerable
用于返回可以单独处理的元素流。这就是为什么该功能实际上被称为异步流,造成了相当多的混乱
转换为任务<IEnumerable<FileUpload>>
最好的解决方案是不转换,而是将签名更改为IEnumerable<FileUpload>
并在创建新FileUpload
实例后立即返回:
private async IAsyncEnumerable<FileUpload> GetFileUploadsAsync(string relativePath)
{
await foreach(var filePath in service.GetFilePathsFromRelativePathAsync(relativePath))
{
var upload = new FileUpload(filePath);
yield return upload;
}
}
您还可以收集所有结果,将它们存储在列表中并返回它们,例如使用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.Async项目为 IAsyncEnumerable 提供 LINQ 运算符,包括ToList ,并且可以在 NuGet上找到。
该代码非常简单,但包含一些优化,例如对来自其他运算符(如 GroupBy 和 Reverse)的数据使用ValueTask
代替和特殊处理,这些运算符必须在产生输出之前消耗整个数据。Task
IAsyncEnumerable