.net core 3.1: 'IAsyncEnumerable<string>' 不包含 'GetAwaiter' 的定义

.net core 3.1: 'IAsyncEnumerable<string>' does not contain a definition for 'GetAwaiter'

我有一个 .net core 3.1 控制台应用程序。

我有一个具有以下签名的方法:

public async IAsyncEnumerable<string> GetFilePathsFromRelativePathAsync(string relativePath)

如果我调用它:

private async Task<IEnumerable<FileUpload>> GetFileUploadsAsync(string relativePath)
{
...
    var filePaths = await service.GetFilePathsFromRelativePathAsync(relativePath);
...
}

我收到以下错误:

Error CS1061 'IAsyncEnumerable' does not contain a definition for 'GetAwaiter' and no accessible extension method 'GetAwaiter' accepting a first argument of type 'IAsyncEnumerable' could be found (are you missing a using directive or an assembly reference?)

正确的语法是:

await foreach(var filePath in service.GetFilePathsFromRelativePathAsync(relativePath))
{
    ....
}

IAsyncEnumerable 用于 return 可以单独处理的元素流。这就是为什么该功能实际上被称为 async streams,造成了相当大的混乱

正在转换为任务>

最好的解决方案是 转换,但尽快将签名更改为 IEnumerable<FileUpload> 和 return 新的 FileUpload 实例他们创建了:

private async IAsyncEnumerable<FileUpload> GetFileUploadsAsync(string relativePath)
{
    await foreach(var filePath in service.GetFilePathsFromRelativePathAsync(relativePath))
    {
        var upload = new FileUpload(filePath);
        yield return upload;
    }
}

您还可以收集所有结果,将它们存储在列表中并 return 它们,例如使用 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 project provides LINQ operators for IAsyncEnumerable, including ToList, and can be found on NuGet.

代码非常简单,但包括一些优化,比如使用 ValueTask 而不是 Task 以及对来自其他运算符(如 GroupBy 和 Reverse)的数据的特殊处理,这些运算符必须使用整个 IAsyncEnumerable 在产生输出之前。