0

0

c# System.Threading.Channels 详解 c# Channel怎么用

畫卷琴夢

畫卷琴夢

发布时间:2026-01-22 01:49:24

|

337人浏览过

|

来源于php中文网

原创

优先选 CreateBounded(capacity),因其可控内存上限;无界通道易致OOM;有界通道需配置 FullMode 避免生产者挂起;Consumer 必须依赖 Complete() 才能安全退出 await foreach。

c# system.threading.channels 详解 c# channel怎么用

Channel.CreateUnbounded 和 CreateBounded 选哪个?

绝大多数新手一上来就用 CreateUnbounded(),觉得“不用管容量,省事”,但这是最容易埋雷的选择。无界通道会无限缓存数据,一旦消费者卡住或处理变慢,内存会持续上涨,最终 OOM——尤其在日志采集、传感器流等高吞吐场景下,这问题来得又快又静默。

真正该按需选:
• 用 CreateBounded(capacity) 控制内存上限,比如 Channel.CreateBounded(1000)
• 显式传 BoundedChannelOptions 配置 FullMode,避免默认 Wait 导致生产者协程被挂起太久;
• 真需要无界语义(如内部管道、短生命周期任务),才用 CreateUnbounded(),但务必搭配超时或背压检测逻辑。

WriteAsync 写不进去?检查 Complete() 和 FullMode

常见现象:生产者调用 await channel.Writer.WriteAsync(item) 后卡住不动,或者直接抛出 InvalidOperationException: The channel has been closed

  • 先确认是否误调了 channel.Writer.Complete() —— 一旦调用,后续所有写入都会失败;
  • 如果是有界通道且满载,WriteAsync 默认会 Wait,直到有空位;若你希望快速失败,改用 TryWrite 或设 FullMode = BoundedChannelFullMode.DropWrite
  • DropNewestDropOldest 适用于滑动窗口类场景(如最近 100 条状态),但注意:丢弃行为是静默的,不抛异常,也不通知生产者。

Consumer 怎么安全读完所有数据?别漏掉 Complete()

消费者用 await foreach (var item in channel.Reader.ReadAllAsync()) 是最简洁的方式,但它**依赖生产者显式调用 channel.Writer.Complete()**。漏掉这句,循环永远不会退出——不是卡死,而是永远挂起等待下一条。

VWO
VWO

一个A/B测试工具

下载

更健壮的做法(尤其多生产者):
• 每个生产者完成时调用 channel.Writer.TryComplete()(线程安全,多次调用无副作用);
• 消费者可结合 channel.Reader.Completion 监听异常;
• 若需手动控制读取节奏,用 await channel.Reader.ReadAsync() + TryRead 判断是否已空或已关闭。

Channel 不是万能队列:和 Dataflow、BlockingCollection 的关键区别

很多人把 Channel 当作“新版 BlockingCollection”,其实它定位更轻:只负责**异步、线程安全的数据暂存与传递**,不带处理逻辑、不支持广播、不内置限流策略。

  • 要 pipeline 式加工(如 TransformBlock → ActionBlock),用 System.Threading.Tasks.Dataflow
  • 要同步阻塞+取消支持+枚举器兼容,BlockingCollection 仍适用(尤其老项目或混合同步/异步场景);
  • Channel 的优势在纯异步高吞吐:比如 ASP.NET Core 中接 HTTP body 流、gRPC server streaming、模拟 PLC 通信——这些场景里,它比 Dataflow 少一层封装,分配更少对象,GC 压力更低。

最常被忽略的一点:Channel 的 Reader 和 Writer 是分离对象,可以跨 Task、跨线程自由传递,但**不能重复使用已 Complete 的 Writer,也不能对已 Complete 的 Reader 调用 ReadAsync**——这类错误不会立刻崩溃,而是在 await 时才抛异常,调试时容易绕远路。

相关专题

更多
string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

338

2023.08.02

php中foreach用法
php中foreach用法

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

45

2025.12.04

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

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

482

2023.08.10

Golang channel原理
Golang channel原理

本专题整合了Golang channel通信相关介绍,阅读专题下面的文章了解更多详细内容。

247

2025.11.14

golang channel相关教程
golang channel相关教程

本专题整合了golang处理channel相关教程,阅读专题下面的文章了解更多详细内容。

342

2025.11.17

http500解决方法
http500解决方法

http500解决方法有检查服务器日志、检查代码错误、检查服务器配置、检查文件和目录权限、检查资源不足、更新软件版本、重启服务器或寻求专业帮助等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

377

2023.11.09

http请求415错误怎么解决
http请求415错误怎么解决

解决方法:1、检查请求头中的Content-Type;2、检查请求体中的数据格式;3、使用适当的编码格式;4、使用适当的请求方法;5、检查服务器端的支持情况。更多http请求415错误怎么解决的相关内容,可以阅读下面的文章。

413

2023.11.14

HTTP 503错误解决方法
HTTP 503错误解决方法

HTTP 503错误表示服务器暂时无法处理请求。想了解更多http错误代码的相关内容,可以阅读本专题下面的文章。

2013

2024.03.12

AO3中文版入口地址大全
AO3中文版入口地址大全

本专题整合了AO3中文版入口地址大全,阅读专题下面的的文章了解更多详细内容。

1

2026.01.21

热门下载

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

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
10分钟--Midjourney创作自己的漫画
10分钟--Midjourney创作自己的漫画

共1课时 | 0.1万人学习

Midjourney 关键词系列整合
Midjourney 关键词系列整合

共13课时 | 0.9万人学习

AI绘画教程
AI绘画教程

共2课时 | 0.2万人学习

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

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