0

0

C#如何使用IAsyncEnumerable C#异步流使用详解

幻夢星雲

幻夢星雲

发布时间:2025-12-22 10:07:02

|

248人浏览过

|

来源于php中文网

原创

IAsyncEnumerable是C# 8.0引入的异步流类型,适用于按需异步生成多个数据项的场景,支持await foreach消费、内存友好、可取消且响应及时。

c#如何使用iasyncenumerable c#异步流使用详解

IAsyncEnumerable 是 C# 8.0 引入的核心异步流类型,用于高效、自然地处理“按需异步生成的多个数据项”,比如分页查询、实时日志、流式 API 响应、大数据集逐块读取等场景。它不是一次性加载全部结果,而是支持 await foreach 消费,每个元素可独立 await,内存友好且响应及时。

什么时候该用 IAsyncEnumerable

当你需要以下任意一种能力时,IAsyncEnumerable 是比 List 或 IEnumerable 更合适的选择:

  • 数据源本身是异步的(如数据库分页查询、HTTP 流式响应、文件分块读取)
  • 不想阻塞线程,也不愿把全部结果缓存在内存里(尤其数据量大或生成耗时)
  • 消费者希望边接收边处理,而不是等所有数据就绪才开始(降低端到端延迟)
  • 需要在迭代中途取消(配合 CancellationToken)

如何定义和返回 IAsyncEnumerable

最常用方式是使用 async yield return 语法(需方法返回 IAsyncEnumerable,且标记为 async):

示例:模拟异步分页获取用户

Python v2.4 中文手册 chm
Python v2.4 中文手册 chm

Python v2.4版chm格式的中文手册,内容丰富全面,不但是一本手册,你完全可以把她作为一本Python的入门教程,教你如何使用Python解释器、流程控制、数据结构、模板、输入和输出、错误和异常、类和标准库详解等方面的知识技巧。同时后附的手册可以方便你的查询。

下载
public async IAsyncEnumerable GetUsersAsync(int pageSize = 10, [EnumeratorCancellation] CancellationToken ct = default)
{
    int page = 0;
    while (true)
    {
        var users = await _apiClient.GetPageAsync(page++, pageSize, ct).ConfigureAwait(false);
        if (users.Length == 0) break;
    foreach (var user in users)
    {
        // 每次 yield return 都可被 await foreach 暂停等待
        yield return user;
    }
}

}

注意:
– 方法签名必须是 async IAsyncEnumerable,不能是 Task>
[EnumeratorCancellation] 是可选但推荐的特性,让调用方传入的 CancellationToken 能自动注入到 yield return 的执行上下文中;
– 不要在 yield return 外部 await 长时间操作(否则会阻塞整个流),应在每次 yield 前完成必要 await。

如何安全消费 IAsyncEnumerable

使用 await foreach(C# 8+),它会自动处理异步枚举器的创建、移动、释放和异常传播:

await foreach (var user in GetUsersAsync(20, cancellationToken))
{
    Process(user); // 同步处理
    await SaveToDbAsync(user); // 也可 await 异步操作
}

关键点:
– 必须在 async 方法内使用,且外层方法需标记为 async;
– 支持直接传入 CancellationToken(会被传递到底层 yield 方法);
– 若在循环中抛出异常,会自动调用 DisposeAsync() 清理资源(前提是底层实现了 IAsyncDisposable);
– 不支持 LINQ 查询语法(如 .Where()、.Select()),但可使用 System.Linq.Async(需 NuGet 包 Microsoft.Bcl.AsyncInterfacesSystem.Linq.Async)。

常见误区与建议

  • 别包装成 Task:返回 Task 就失去了流式优势,消费者必须 await 完才拿到枚举器
  • 避免在 yield return 中做 CPU 密集型工作:这会阻塞异步流线程,考虑用 Task.Run 分离,但要权衡调度开销
  • 谨慎共享状态:多个 await foreach 并发消费同一 IAsyncEnumerable 实例时,行为未定义(多数实现不支持重入),应确保每个消费方获得独立流实例
  • 注意取消时机:CancellationToken 在每次 MoveNextAsync() 时检查,若某次 yield 返回后立刻取消,后续不会执行 —— 但当前正在 await 的操作仍可能继续运行,需在内部主动检查 ct.IsCancellationRequested

基本上就这些。IAsyncEnumerable 不复杂但容易忽略其“流式”本质——它不是异步版的 List,而是一条可暂停、可取消、低内存占用的数据流水线。

相关专题

更多
php中foreach用法
php中foreach用法

本专题整合了php中foreach用法的相关介绍,阅读专题下面的文章了解更多详细教程。

42

2025.12.04

线程和进程的区别
线程和进程的区别

线程和进程的区别:线程是进程的一部分,用于实现并发和并行操作,而线程共享进程的资源,通信更方便快捷,切换开销较小。本专题为大家提供线程和进程区别相关的各种文章、以及下载和课程。

481

2023.08.10

数据库三范式
数据库三范式

数据库三范式是一种设计规范,用于规范化关系型数据库中的数据结构,它通过消除冗余数据、提高数据库性能和数据一致性,提供了一种有效的数据库设计方法。本专题提供数据库三范式相关的文章、下载和课程。

346

2023.06.29

如何删除数据库
如何删除数据库

删除数据库是指在MySQL中完全移除一个数据库及其所包含的所有数据和结构,作用包括:1、释放存储空间;2、确保数据的安全性;3、提高数据库的整体性能,加速查询和操作的执行速度。尽管删除数据库具有一些好处,但在执行任何删除操作之前,务必谨慎操作,并备份重要的数据。删除数据库将永久性地删除所有相关数据和结构,无法回滚。

2074

2023.08.14

vb怎么连接数据库
vb怎么连接数据库

在VB中,连接数据库通常使用ADO(ActiveX 数据对象)或 DAO(Data Access Objects)这两个技术来实现:1、引入ADO库;2、创建ADO连接对象;3、配置连接字符串;4、打开连接;5、执行SQL语句;6、处理查询结果;7、关闭连接即可。

347

2023.08.31

MySQL恢复数据库
MySQL恢复数据库

MySQL恢复数据库的方法有使用物理备份恢复、使用逻辑备份恢复、使用二进制日志恢复和使用数据库复制进行恢复等。本专题为大家提供MySQL数据库相关的文章、下载、课程内容,供大家免费下载体验。

255

2023.09.05

vb中怎么连接access数据库
vb中怎么连接access数据库

vb中连接access数据库的步骤包括引用必要的命名空间、创建连接字符串、创建连接对象、打开连接、执行SQL语句和关闭连接。本专题为大家提供连接access数据库相关的文章、下载、课程内容,供大家免费下载体验。

323

2023.10.09

数据库对象名无效怎么解决
数据库对象名无效怎么解决

数据库对象名无效解决办法:1、检查使用的对象名是否正确,确保没有拼写错误;2、检查数据库中是否已存在具有相同名称的对象,如果是,请更改对象名为一个不同的名称,然后重新创建;3、确保在连接数据库时使用了正确的用户名、密码和数据库名称;4、尝试重启数据库服务,然后再次尝试创建或使用对象;5、尝试更新驱动程序,然后再次尝试创建或使用对象。

410

2023.10.16

高德地图升级方法汇总
高德地图升级方法汇总

本专题整合了高德地图升级相关教程,阅读专题下面的文章了解更多详细内容。

27

2026.01.16

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
CSS3 教程
CSS3 教程

共18课时 | 4.6万人学习

PostgreSQL 教程
PostgreSQL 教程

共48课时 | 7.3万人学习

Django 教程
Django 教程

共28课时 | 3.2万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号