.net 核心 3.1:“IAsyncEnumerable<string>”不包含“GetAwaiter”的定义

Posted

技术标签:

【中文标题】.net 核心 3.1:“IAsyncEnumerable<string>”不包含“GetAwaiter”的定义【英文标题】:.net core 3.1: 'IAsyncEnumerable<string>' does not contain a definition for 'GetAwaiter' 【发布时间】:2020-05-25 15:35:42 【问题描述】:

我有一个 .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);
...

我收到以下错误:

错误 CS1061 'IAsyncEnumerable' 不包含定义 对于 'GetAwaiter' 并且没有可访问的扩展方法 'GetAwaiter' 接受“IAsyncEnumerable”类型的第一个参数可能是 找到(您是否缺少 using 指令或程序集 参考?)

【问题讨论】:

【参考方案1】:

正确的语法是:

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

    ....

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

转换为任务>

最好的解决方案是转换,而是将签名更改为IEnumerable&lt;FileUpload&gt;,并在创建后立即返回新的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,可以找到 on NuGet。

代码非常简单,但包含一些优化,例如使用 ValueTask 代替 Task 以及对来自其他运算符(如 GroupBy 和 Reverse)的数据进行特殊处理,这些运算符必须在生成之前消耗整个 IAsyncEnumerable他们的输出。

【讨论】:

好吧,这很有趣...有没有办法在没有 foreach 的情况下从 IAsyncEnumerable 转到 Task>? 您可以将您的方法改为IAsyncEnumerable&lt;FileUpload&gt;,并在生成新的 FileUpload 实例后立即更改为yield return。或者您可以使用(或复制)System.Linq.Async ToList 运算符中的代码将每个项目添加到列表中并在末尾返回列表 请在第一个和第二个 foreach 循环示例中将 from 重命名为 to @Deano 你的意思是in? 正确。嗬!谢谢老兄。

以上是关于.net 核心 3.1:“IAsyncEnumerable<string>”不包含“GetAwaiter”的定义的主要内容,如果未能解决你的问题,请参考以下文章

.net 核心 3.1:“IAsyncEnumerable<string>”不包含“GetAwaiter”的定义

如何从剃刀视图提交具有动态列表的模型中的列表? ASP.NET 核心 3.1

HTTP 错误 405 | [HttpPost] ASP.NET MVC 核心 3.1

将 [Authorize] 添加到控制器无法重定向到身份登录路由。 ASP.NET 核心 3.1 MVC

当用户的 AD 身份验证失败时如何导航到自定义访问被拒绝页面(.net 3.1 核心与 OpenIDConnect Azure AD 身份验证)

流分析服务和 WebApp 服务之间的数据流 (.NET core 3.1)