news 2026/3/30 8:59:24

.NET 10 中无缓冲通道 Rendezvous Channel

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
.NET 10 中无缓冲通道 Rendezvous Channel

.NET 10 中无缓冲通道 Unbuffered Channel 支持(Rendezvous Channel)

Intro

在 .NET 10 中,System.Threading.Channels引入了一项令人兴奋的新功能:支持创建容量为 0 的有界通道,又可以称为无缓冲通道,也称为Rendezvous Channel(会合通道)。

What

在之前的 .NET 版本中,创建有界通道时容量必须至少为 1,否则会抛出异常。而从 .NET 10 开始,您可以使用Channel.CreateBounded(0)创建一个容量为 0 的通道,这样就没有任何缓冲,一个是无缓冲的通道,Unbuffered Channel。

容量表示通道可以缓冲的项目数量。当容量为 0 时,通道无法缓冲任何内容,这使其成为一个会合点(Rendezvous), :读取者和写入者必须同时在通道处等待,才能直接从写入者传递数据到读取者。

这种语义与其他语言和库中的概念一致。例如,在其他语言中,如果不指定缓冲区大小或指定大小为 0,您同样会得到一个无缓冲的会合通道。

使用场景

无缓冲通道确保在业务工作流中的关键交接点同步

使用带缓冲通道时,发送方可以在没有确认的情况下继续,这可能导致消费和发送的速率不匹配从而导致一些资源不匹配的问题。

主要使用场景如下:

1. 同步和协调

  • • 确保发送者和接收者在完全相同的时间点同步

  • • 保证操作完成后再继续

2. 交接/直接传输

  • • 从生产者到消费者的数据直接传输,没有中间存储

  • • 确保数据被接收后发送者才继续

  • • 当你需要确认数据已被接受时非常有用

3. 信号/事件

  • • 信号表示某个事件已经发生

  • • 工作线程通知完成或就绪

  • • 例如:使用done通道来信号goroutine完成

4. 速率限制

  • • 自然的反压机制 - 如果接收者未准备好,发送者会被阻塞

  • • 防止数据过多导致接收者不堪重负

  • • 迫使生产者降低速度以适应消费者的处理速度,尤其是有资源限制或要严格控制资源使用的场景

5. 请求-响应模式

  • • 实现同步请求-响应通信

  • • 确保请求完全处理后再继续

6. 资源协调

  • • 协调对共享资源的访问

  • • 确保管道中各阶段之间工作的有序交接

无缓冲通道的关键特性是提供保证同步- 双方必须同时准备好,这使得它们在需要严格协调而不是异步通信时非常理想。

使用示例

基本用法

// 创建一个容量为 0 的有界通道 var channel = Channel.CreateBounded<int>(0); // 写入操作会阻塞,直到有读取者准备好接收 var writeTask = channel.Writer.WriteAsync(42); // 读取操作会阻塞,直到有写入者准备好发送 var value = await channel.Reader.ReadAsync(); // 返回 42 await writeTask; // 写入完成

使用BoundedChannelOptions配置

var options = new BoundedChannelOptions(0) { FullMode = BoundedChannelFullMode.Wait, AllowSynchronousContinuations = false }; var channel = Channel.CreateBounded<string>(options);

主要特性

1.同步传递

  • • 读取者和写入者必须同时准备好才能完成数据传递

  • • 没有缓冲,数据直接从写入者传递到读取者

2.支持多种完整模式

Rendezvous Channel 支持BoundedChannelFullMode的不同模式:

  • Wait:写入操作等待读取者就绪(默认行为)

  • DropWrite:如果没有读取者,立即丢弃写入的数据

  • DropOldest/DropNewest:与DropWrite行为相同(因为没有缓冲)

var channel = Channel.CreateBounded<int>(new BoundedChannelOptions(0) { FullMode = BoundedChannelFullMode.DropWrite }, droppedItem => Console.WriteLine($"丢弃的项目: {droppedItem}")); channel.Writer.TryWrite(100); // 如果没有读取者,立即成功并调用回调

3.Count 属性始终为 0

由于没有缓冲,channel.Reader.Count始终返回 0,即使有等待的写入者或读取者。

var channel = Channel.CreateBounded<int>(0); var write1 = channel.Writer.WriteAsync(1); // 阻塞 var write2 = channel.Writer.WriteAsync(2); // 阻塞 Console.WriteLine(channel.Reader.Count); // 输出: 0

性能考虑

Rendezvous Channel 在某些场景下可以提供更好的性能和更清晰的语义:

  • 无内存分配:不需要为缓冲分配空间

  • 直接传递:数据直接从生产者传递到消费者,没有中间存储

  • 同步协调:自然实现生产者-消费者之间的节流控制

适用场景

Rendezvous Channel 特别适合以下场景:

  1. 1.严格的生产者-消费者同步:需要确保每个生产的项都被立即消费

  2. 2.流量控制:自然限制生产者的速度以匹配消费者

  3. 3.协调模式:实现类似 CSP(Communicating Sequential Processes)风格的并发模式

  4. 4.资源管理:确保资源在传递时不会积压

生产者消费者同步示例

var channel = Channel.CreateBounded<WorkItem>(0); var producer = Task.Run(async () => { for (var i = 0; i < 5; i++) { Console.WriteLine($"[Producer]准备生产项目 {i} {DateTimeOffset.Now}"); await channel.Writer.WriteAsync(new WorkItem(i)); Console.WriteLine($"[Producer]项目 {i} 已交付 {DateTimeOffset.Now}"); } channel.Writer.Complete(); }); var consumer = Task.Run(async () => { await foreach (var item in channel.Reader.ReadAllAsync()) { Console.WriteLine($"[Consumer]接收到项目 {item.Id} {DateTimeOffset.Now}"); await Task.Delay(1000); // 模拟处理 Console.WriteLine($"[Consumer]项目 {item.Id} 处理完成 {DateTimeOffset.Now}"); } }); await Task.WhenAll(producer, consumer); file sealed record WorkItem(int Id);

输出示例:

sample output

从输出结果可以看出,在消费者完成前一个消息的消费任务之前,生产者是不能生产第二个任务的,只有前面的完成了后面的才能生产成功,从而保证发送的速率和消费的速率持平。

More

容量为 0 的无缓冲通道(Rendezvous Channel)为 .NET 开发者提供了一种强大的新工具,用于实现严格的同步和流量控制。

如果您的应用需要精确的生产者-消费者协调或流量控制,这项新功能将是一个不错选择。

References

  • • https://github.com/dotnet/runtime/pull/116097

  • • https://github.com/dotnet/runtime/issues/94046

  • • https://learn.microsoft.com/en-us/dotnet/api/system.threading.channels.channel?view=net-10.0&WT.mc_id=DT-MVP-5004222

  • • https://github.com/WeihanLi/SamplesInPractice/blob/main/net10sample/Net10Samples/ChannelSample.cs

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/3/28 10:52:06

ExcalidrawER图制作:数据库设计可视化

Excalidraw 与数据库设计&#xff1a;当手绘白板遇上智能建模 在一次产品评审会上&#xff0c;你是否经历过这样的场景&#xff1f;产品经理在纸上草草画出几个方框和连线&#xff0c;说&#xff1a;“我们大概需要一个用户表、订单表&#xff0c;它们之间是一对多关系……”而…

作者头像 李华
网站建设 2026/3/29 1:56:59

Excalidraw自动伸缩部署:Kubernetes集群实践

Excalidraw自动伸缩部署&#xff1a;Kubernetes集群实践 在远程协作日益成为常态的今天&#xff0c;团队对高效、直观的可视化工具需求急剧上升。Excalidraw作为一款开源手绘风格白板工具&#xff0c;凭借其极简设计和强大的实时协作能力&#xff0c;迅速在技术架构图绘制、产品…

作者头像 李华
网站建设 2026/3/26 20:33:15

Excalidraw CDN加速部署方案:全球访问提速

Excalidraw CDN加速部署方案&#xff1a;全球访问提速 在跨国团队协作日益频繁的今天&#xff0c;一个看似微小的技术细节——前端资源加载速度&#xff0c;往往成为决定产品体验生死的关键。设想一下&#xff1a;欧洲的产品经理正准备与印度的开发团队进行一场关键架构评审&a…

作者头像 李华
网站建设 2026/3/26 20:32:39

Excalidraw源码阅读笔记:核心模块架构剖析

Excalidraw源码阅读笔记&#xff1a;核心模块架构剖析 在远程协作成为常态的今天&#xff0c;一个简单却高效的可视化工具往往能决定一场头脑风暴的成败。我们见过太多功能臃肿、操作复杂的绘图软件——它们擅长制作“完美”的图表&#xff0c;却在快速表达想法时显得笨拙不堪。…

作者头像 李华
网站建设 2026/3/27 4:53:11

打印机驱动安装全攻略:从准备到验证一步到位

在日常办公和家庭使用中&#xff0c;打印机驱动安装不当常常导致设备无法正常工作&#xff0c;轻则打印卡顿&#xff0c;重则直接提示“驱动未安装”或“设备无法识别”。其实&#xff0c;只要掌握正确的流程和技巧&#xff0c;打印机驱动安装就能高效完成。本文将结合不同操作…

作者头像 李华
网站建设 2026/3/29 11:18:59

官网-职工带薪年休假条例

官网:职工带薪年休假条例(国务院令第514号)_中华人民共和国中央人民政府门户网站 第一条 为了维护职工休息休假权利,调动职工工作积极性,根据劳动法和公务员法,制定本条例。 第二条* 机关、团体、企业、事业单位、民办非企业单位、有雇工的个体工商户等单位的职工连续…

作者头像 李华