如何在 C# 8 中使用 Channels
在面对 生产者-消费者
的场景下, 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的更多相关文章
- 如何在 Visual Studio 中使用 Git 同步代码到 CodePlex
开源社区不管在国内还是国外都很火热,微软也曾因为没有开源而倍受指责,但是随着 .Net framework.ASP.Net MVC等框架的逐渐开源,也让大家看到了微软开源的步伐.CodePlex 则是 ...
- 如何在Linux服务器中隐藏PHP版本
通常,大多数默认设置安装的web服务器存在信息泄露,这其中之一就是PHP.PHP 是如今流行的服务端html嵌入式语言(之一?).在如今这个充满挑战的时代,有许多攻击者会尝试发现你服务端的漏洞.因此, ...
- [Laravel-Swagger]如何在 Laravel 项目中使用 Swagger
如何在 Laravel 项目中使用 Swagger http://swagger.io/getting-started/ 安装依赖 swagger-php composer require zirco ...
- 如何在win7系统中安装redis
转载于:http://www.itxuexiwang.com/a/shujukujishu/redis/2016/0216/92.html?1455871954 如何在win7系统中安装redis ...
- 如何在 ETL 项目中统一管理上百个 SSIS 包的日志和包配置框架
一直准备写这么一篇有关 SSIS 日志系统的文章,但是发现很难一次写的很完整.因为这篇文章的内容可扩展的性太强,每多扩展一部分就意味着需要更多代码,示例和理论支撑.因此,我选择我觉得比较通用的 LOG ...
- 如何在window Form中使用Font Awesome?
随着技术的发展,web上以前的图片按钮现在逐步换成了图标字体,这些图标字体是矢量的,矢量图意味着每个图标都能在所有大小的屏幕上完美呈现,可以随时更改大小和颜色,而且不失真,真心给人一种“高大上”的感觉 ...
- 如何在JDK1.8中愉快地处理日期和时间
如何在JDK1.8中愉快地处理日期和时间 JDK1.8新增了LocalDate和LocalTime接口,为什么要搞一套全新的处理日期和时间的API?因为旧的java.util.Date实在是太难用了. ...
- 如何在C语言中调用Swift函数
在Apple官方的<Using Swift with Cocoa and Objectgive-C>一书中详细地介绍了如何在Objective-C中使用Swift的类以及如何在Swift中 ...
- 如何在ASP.Net中实现RSA加密
在我们实际运用中,加密是保证数据安全的重要手段.以前使用ASP时,对数据加密可以使用MD5和SHA1算法,这两种算法虽然快捷有效,但是无法对通过它们加密的密文进行反运算,即是解密.因此需要解密数据的场 ...
随机推荐
- 笔记-EF Core 并发冲突与令牌
并发标记并发分悲观并发和乐观并发.悲观并发:比如有两个用户A,B,同时登录系统修改一个文档,如果A先进入修改,则系统会把该文档 锁住,B就没办法打开了,只有等A修改完,完全退出的时候B才能进入修改.乐 ...
- 技术分享: CSS3 系列
技术分享: CSS3 系列 css 一键换肤 css 打印样式,媒体查询 css 禁用选择 css 性能优化 css 计算单位 css 3D 特效 refs xgqfrms 2012-2020 www ...
- Graphviz - Graph Visualization Software 开源可视化绘图工具(visio 类)
http://www.graphviz.org/Download_windows.php Welcome to Graphviz Available translations: Romanian, ...
- Battery API All In One
Battery API All In One https://caniuse.com/?search=Battery navigator.getBattery() /* Promise {<pe ...
- How to Use RSS on Your Website
RSS feed 1 <!DOCTYPE html> <html lang="en"> <head> <meta charset=&quo ...
- website captcha
website captcha 验证码 hCaptcha hCaptcha通过询问对人类来说很容易且对机器来说很困难的简单问题,可以帮助您喜欢的Web服务阻止机器人,垃圾邮件和滥用行为. https: ...
- OpenCV & Web Assembly & Web Worker
OpenCV & Web Assembly & Web Worker opencv-in-the-web https://aralroca.com/blog/opencv-in-the ...
- Flutter for Desktop
Flutter for Desktop https://flutter.dev/desktop https://github.com/flutter/flutter/wiki/Desktop-shel ...
- ESLint error level
ESLint error level https://eslint.org/docs/user-guide/getting-started#configuration .eslintrc { &quo ...
- html fragment & html template & virtual DOM & web components
html fragment & html template & virtual DOM https://developer.mozilla.org/en-US/docs/Web/API ...