在面对  生产者-消费者 的场景下, netcore 提供了一个新的命名空间 System.Threading.Channels 来帮助我们更高效的处理此类问题,有了这个 Channels 存在, 生产者消费者 可以各自处理自己的任务而不相互干扰,有利于两方的并发处理,这篇文章我们就来讨论下如何使用 System.Threading.Channels

Dataflow vs Channel

System.Threading.Tasks.Dataflow 命名空间下提供了一个数据流库,主要封装了 存储处理 两大块,该库专注于 pipeline 处理,而 System.Threading.Tasks.Channels 主要专注于 存储 这块,从单一职责上来说,在 生产者-消费者 场景下,Channels 比 Dataflow 性能要高得多。

为什么要使用 Channels

可以利用 Channels 来实现 生产者和消费者 之间的解耦,大体上有两个好处:

  • 生产者 和 消费者 是相互独立的,两者可以并行执行。

  • 如果生产者不给力,可以创建多个的生产者,如果消费者不给力,可以创建更多的消费者。

总的来说,在 生产者-消费者 模式下可以帮助我们提高应用程序的吞吐率。

安装 System.Threading.Channels

要想使用 Channel,需要用 nuget 引用 System.Threading.Channels 包,还可以通过 Visual Studio 2019 的 NuGet package manager 可视化界面安装 或者 通过 NuGet package manager 命令行工具输入以下命令:


dotnet add package System.Threading.Channels

创建 channel

本质上来说,你可以创建两种类型的 channel,一种是有限容量的 bound channel,一种是无限容量的 unbound channel,接下来的问题是,如何创建呢?Channels 提供了两种 工厂方法 用于创建,如下代码所示:

  • CreateBounded<T> 创建的 channel 是一个有消息上限的通道。

  • CreateUnbounded<T> 创建的 channel 是一个无消息上限的通道。

下面的代码片段展示了如何创建 unbounded channel,并且只能存放 string 类型。

static void Main(string[] args){var channel = Channel.CreateUnbounded<string>();}

对了,Bounded channel 还提供了一个 FullMode 属性,用于指定当 channel 已满时该如何对插入的 message 进行处理,通常有四种做法。

  • Wait

  • DropWrite

  • DropNewest

  • DropOldest

下面的代码片段展示了如何在 Bounded channel 上使用 FullMode。

static void Main(string[] args){var channel = Channel.CreateBounded<string>(new BoundedChannelOptions(1000){FullMode = BoundedChannelFullMode.Wait});}

将消息写入到 channel

要想将 message 写入到 channel,可以使用 WriteAsync() 方法,如下代码所示:

static async Task Main(string[] args){var channel = Channel.CreateBounded<string>(new BoundedChannelOptions(1000){FullMode = BoundedChannelFullMode.Wait});await channel.Writer.WriteAsync("Hello World!");}

从 channel 中读取消息

要想从 channel 中读取 message,可以使用 ReadAsync(),如下代码所示:

static async Task Main(string[] args){var channel = Channel.CreateBounded<string>(new BoundedChannelOptions(1000){FullMode = BoundedChannelFullMode.Wait});while (await channel.Reader.WaitToReadAsync()){if (channel.Reader.TryRead(out var message)){Console.WriteLine(message);}}}

System.Threading.Channels 例子

下面是完整的代码清单,展示了如何从 channel 中读写 message。

class Program{static async Task Main(string[] args){await SingleProducerSingleConsumer();Console.ReadKey();}public static async Task SingleProducerSingleConsumer(){var channel = Channel.CreateUnbounded<int>();var reader = channel.Reader;for (int i = 0; i < 10; i++){await channel.Writer.WriteAsync(i + 1);}while (await reader.WaitToReadAsync()){if (reader.TryRead(out var number)){Console.WriteLine(number);}}}}

可以看到,控制台中输出了数字 1-10,这些数字正是 Writer 写入到 channel 中的,对吧。

总的来说,要想使用 生产者-消费者 场景,有几种实现途径,比如:BlockingCollection 和 TPL Dataflow,但本篇介绍的 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

如何在 C# 8 中使用 Channels相关推荐

  1. 如何在Tensorflow.js中处理MNIST图像数据

    by Kevin Scott 凯文·斯科特(Kevin Scott) 如何在Tensorflow.js中处理MNIST图像数据 (How to deal with MNIST image data i ...

  2. 微软teams软件_如何在Microsoft Teams中创建和管理团队

    微软teams软件 With its friendly user interface, seamless integration with Office 365, and low price tag, ...

  3. ios opencv图片处理_如何在 iOS 工程中使用 OpenCV?

    前言 OpenCV ,是一个开源的跨平台计算机视觉和机器学习库,通俗点的说,就是他给计算机提供了一双眼睛,一双可以从图片中获取信息的眼镜,从而完成人脸识别.去红眼.追踪移动物体等等的图像相关的功能.更 ...

  4. Windows 系统如何在 C++ 项目中使用第三方库

    要使用第三方库, 首先需要进行安装. 在没有 vcpkg 以前, 安装第三方库需要在本地进行编译与链接, 而如果我们是新手, 则必然会遇到这样或那样难以解决的问题. 但有了 vcpkg 以后就不一样, ...

  5. 如何在sqlite3连接中创建并调用自定义函数

    #!/user/bin/env python # @Time :2018/6/8 14:44 # @Author :PGIDYSQ #@File :CreateFunTest.py '''如何在sql ...

  6. Iar环境c语言调用汇编函数,如何在IAR EWARM中通过内联汇编程序在另一个模块中调用C函数?...

    我在硬故障处理程序中有一些程序集.程序集基本上是为了传递当前堆栈指针作为参数(在R0中).它看起来像这样...如何在IAR EWARM中通过内联汇编程序在另一个模块中调用C函数? __asm(&quo ...

  7. 学习如何在AutoCad土木工程中绘制建筑设计图

    学习如何在AutoCad中绘制建筑设计图从平面图到AutoCad土木工程中的整栋建筑 你会学到: 如何绘制房屋地图 如何绘制建筑设计 如何从AutoCad打印或出图 AutoCaD使用 AutoCaD ...

  8. 如何在OS X中打印到PDF文件

    如何在OS X中打印文件到PDF文件? 其实不需要安装任何其他软件,OS X本身支持打印到PDF文件这个功能. 具体操作详见下面文章: Want to save a document or web p ...

  9. 转 如何在IOS设备中去掉屏幕上的status bar

    引入 如何在IOS设备中去掉屏幕上的status bar,即:不显示设备上方的[网络.时间.电池??]条? 操作 方法一: 在-info.list项目文件中,加上"Status bar is ...

最新文章

  1. SQL Server 入门复习(2008)图解
  2. NLP—word2vec词向量简介
  3. qemu运行linux内核很慢,linux – qcow2图像的qemu存储性能非常慢
  4. flyme禁止系统更新_魅族Flyme更新8.1.2.3A:重要系统更新!
  5. 进程隐藏与进程保护(SSDT Hook 实现)(一)
  6. java mysql实现原理_MySQL事务实现原理
  7. 给它一个REST:对您的API使用GraphQL
  8. duckduckgo 国内_DuckDuckGo的Instant Answers项目的7课
  9. windows环境下安装zookeeper教程详解(单机版)
  10. 3. redis的超时,事务,watch
  11. php 对象 堆栈,PHP对象在内存堆栈中的分配
  12. JAVA商城系统开发 VS PHP商城系统开发
  13. android nfc的用法,Android下NFC的简单使用
  14. 10mbps 局域网组播_80211 组播速率及组播转单播
  15. java随机昵称_Java随机产生中文昵称
  16. 鸿蒙系统没有录屏,这15+项高效又实用的功能更新,一定别错过!
  17. android 平板z97,生命在于折腾 iGame Z97也能玩Android
  18. 通信达股票数据格式读取程序
  19. 高效工作的一个绝招:一心二用(听歌,听知识等)
  20. 使用HTML5自制视频控件

热门文章

  1. 一台服务部署多个tomcat注意事项
  2. Managing Gigabytes--文本压缩
  3. Linux内核里的“智能指针” (续)
  4. 学习使用RIA Framework Flex创建MySQL管理UI(初学Flex实例教程)
  5. 基于Visual C++2010与windows SDK fo windows7开发windows7平台的tabletpc应用(1)-手写数学公式输入...
  6. 解决VS2010 beta2 安装后html标签和script智能提示不起作用的问题
  7. 养鹿专辑二:恋鹿篇之枕着老婆的梦编程
  8. stm32cubeide外部中断_【STM32】HAL库 STM32CubeMX教程三----外部中断(HAL库GPIO讲解)
  9. 甘特图看起来很生硬?教你使用智能颜色装饰你的甘特图!(二)
  10. zookeeper和etcd有状态服务部署