当前位置: 首页 > 科技观察

如何在C#8中使用Channel

时间:2023-03-17 19:33:24 科技观察

文章转载请联系码农阅读公众号。面对生产者-消费者场景,netcore提供了一个新的命名空间System.Threading.Channels来帮助我们更高效的处理此类问题。有了这个Channel的存在,生产者和消费者可以分别处理各自的任务,互不干扰,有利于双方的并发处理。在本文中,我们将讨论如何使用System.Threading.Channels。DataflowvsChannel在System.Threading.Tasks.Dataflow命名空间下提供了一个数据流库,主要封装了存储和处理两大块。该库侧重于流水线处理,而System.Threading.Tasks.Channels主要侧重于存储,在单一职责方面,在生产者-消费者场景下,Channels的性能远高于Dataflow。为什么要使用频道?Channels可以用来实现生产者和消费者之间的解耦。一般有两个好处:生产者和消费者相互独立,两者可以并行执行。如果生产者弱,可以创建多个生产者,如果消费者弱,可以创建更多消费者。总的来说,在生产者消费者模式下可以帮助我们提高应用的吞吐量。安装System.Threading.Channels要使用Channel,需要使用nuget引用System.Threading.Channels包。也可以通过VisualStudio2019的NuGet包管理器可视化界面安装,或者通过NuGet包管理器命令行工具输入如下命令:dotnetaddpackageSystem.Threading.Channels创建通道本质上,可以创建两种类型的通道,一种是一个容量有限的绑定通道,另一个是容量无限的未绑定通道。下一个问题是,如何创建它?Channels提供了两种工厂方法用于创建,如下代码所示:CreateBounded创建的通道是一个有消息上限的通道。CreateUnbounded创建的通道是无界通道。下面的代码片段展示了如何创建一个只能存储字符串类型的无界通道。staticvoidMain(string[]args){varchannel=Channel.CreateUnbounded();}顺便说一下,Bounded通道还提供了一个FullMode属性来指定当通道已满时如何处理插入的消息。通常有四种方式。WaitDropWriteDropNewestDropOldest下面的代码片段显示了如何在有界通道上使用FullMode。staticvoidMain(string[]args){varchannel=Channel.CreateBounded(newBoundedChannelOptions(1000){FullMode=BoundedChannelFullMode.Wait});}将消息写入通道要将消息写入通道,可以使用WriteAsync()方法,如下代码所示:");}从通道读取消息要从通道读取消息,可以使用ReadAsync(),如下代码所示:。等待});while(awaitchannel.Reader.WaitToReadAsync()){if(channel.Reader.TryRead(outvarmessage)){Console.WriteLine(message);}}}System.Threading.Channels下面的例子是完整的从频道写消息。classProgram{staticasyncTaskMain(string[]args){awaitSingleProducerSingleConsumer();Console.ReadKey();}publicstaticasyncTaskSingleProducerSingleConsumer(){varchannel=Channel.CreateUnbounded();varreader=channel.Reader;for(inti=0;i<10;i++){awaitchannel.Writer.WriteAsync(i+1);}while(awaitreader.WaitToReadAsync()){if(reader.TryRead(outvarnumber)){Console.WriteLine(number);}}}}可以看到,控制台输出1-10的数字,这些数字是Writer写入通道的吧?一般来说,如果要使用producer-consumer的场景,有几种实现方式,比如:BlockingCollection和TPLDataflow,但是本文介绍的Channels比前两者性能更高,更多关于Channels的细节,我会在以后的文章中讨论,如果你现在想知道,可以参考MSDN:https://docs.microsoft.com/en-us/dotnet/api/system.threading.channels?view=netcore-3.0翻译链接:https://www.infoworld.com/article/3445156/how-to-use-systemthreadingchannels-in-net-core.html