贝利信息

c# Channel 的 Bounded 和 Unbounded 模式有什么区别

日期:2026-01-14 00:00 / 作者:畫卷琴夢
应使用 Channel.CreateBounded 控制内存水位防OOM,如日志采集中生产5000/s、消费800/s时设Capacity=1000,满时可Wait/DropOldest等;CreateUnbounded非无限内存,仅简化背压,需谨慎避免持续积压。

什么时候该用 Channel.CreateBounded

当你需要控制内存水位、防止生产者把消费者“拖垮”时,必须选有界通道。比如:实时日志采集服务中,上游每秒写入 5000 条事件,下游单个消费者每秒最多处理 800 条——这时若用无界通道,几秒内就可能堆积数万条未消费消息,OutOfMemoryException 风险极高。

为什么 Channel.CreateUnbounded 不等于“随便用”?

它只是没有显式容量限制,但不意味着能无限吃内存。底层仍是托管堆上的对象集合,一旦生产速度持续高于消费速度,GC 压力飙升,最终照样 OOM。它真正的价值在于简化背压逻辑,而非纵容失控。

WriteAsync 在两种模式下行为差异极大

表面看都是 await 写入,但背后调度逻辑完全不同:

别忽略 Reader/Writer 的并发安全配置

默认创建的 Channel 允许多生产者多消费者,但如果你实际只用单线程生产+单线程消费,却没关掉多余同步开销,性能反而下降。

真正难的不是选 Bounded 还是 Unbounded,而是预估好你的 Capacity 值和 FullMode 策略是否匹配业务语义。比如金融交易系统丢数据不可接受,那宁可 Wait 卡住也不能 DropOldest;而监控指标上报丢了最近几秒数据问题不大,但卡住会导致整个采集链路雪崩。