2026/4/5 19:25:54
网站建设
项目流程
wordpress侧面导航插件,百度seo有用吗,dedecms网站地图修改,开发板种类.NET 10 中无缓冲通道 Unbuffered Channel 支持#xff08;Rendezvous Channel#xff09;Intro在 .NET 10 中#xff0c;System.Threading.Channels 引入了一项令人兴奋的新功能#xff1a;支持创建容量为 0 的有界通道#xff0c;又可以称为无缓冲通道#xff0c;也称为….NET 10 中无缓冲通道 Unbuffered Channel 支持Rendezvous ChannelIntro在 .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.CreateBoundedint(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.CreateBoundedstring(options);主要特性1.同步传递• 读取者和写入者必须同时准备好才能完成数据传递• 没有缓冲数据直接从写入者传递到读取者2.支持多种完整模式Rendezvous Channel 支持BoundedChannelFullMode的不同模式•Wait写入操作等待读取者就绪默认行为•DropWrite如果没有读取者立即丢弃写入的数据•DropOldest/DropNewest与DropWrite行为相同因为没有缓冲var channel Channel.CreateBoundedint(new BoundedChannelOptions(0) { FullMode BoundedChannelFullMode.DropWrite }, droppedItem Console.WriteLine($丢弃的项目: {droppedItem})); channel.Writer.TryWrite(100); // 如果没有读取者立即成功并调用回调3.Count 属性始终为 0由于没有缓冲channel.Reader.Count始终返回 0即使有等待的写入者或读取者。var channel Channel.CreateBoundedint(0); var write1 channel.Writer.WriteAsync(1); // 阻塞 var write2 channel.Writer.WriteAsync(2); // 阻塞 Console.WriteLine(channel.Reader.Count); // 输出: 0性能考虑Rendezvous Channel 在某些场景下可以提供更好的性能和更清晰的语义•无内存分配不需要为缓冲分配空间•直接传递数据直接从生产者传递到消费者没有中间存储•同步协调自然实现生产者-消费者之间的节流控制适用场景Rendezvous Channel 特别适合以下场景1.严格的生产者-消费者同步需要确保每个生产的项都被立即消费2.流量控制自然限制生产者的速度以匹配消费者3.协调模式实现类似 CSPCommunicating Sequential Processes风格的并发模式4.资源管理确保资源在传递时不会积压生产者消费者同步示例var channel Channel.CreateBoundedWorkItem(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?viewnet-10.0WT.mc_idDT-MVP-5004222• https://github.com/WeihanLi/SamplesInPractice/blob/main/net10sample/Net10Samples/ChannelSample.cs