Dotnet Core下的Channel, 你用了吗?
今天给大家分享一个微软官方的好东西:Channel。
前言
今天给大家分享一个微软官方的生产者/消费者方案的特性解决:Channel。
Channel在System.Threading.Channels
命名空间下,Core 2.1使用时,需要从Nuget上安装。
% dotnet add package System.Threading.Channels
而在Core 3.0 preview 7开始,就直接包含在框架中了。
这是一个相对较新的特性。从Core 2.1开始加入,现在版本是5.0.0(嗯,这个版本号有点骗人,Channel的第一个版本就是4.5.0)。
Channel能做什么?
逻辑上,Channel实际就是一个高效的、线程安全的队列,支持在生产者和消费者之间传递数据。
利用Channel,通过发布和订阅,可以将生产者和消费者分开。生产者Producer负责接收请求,并写入Channel,而消费者Consumer为每个进入Channel的数据执行处理。这样做,一方面可以使生产者和消费者并行工作来提高性能,另一方面,可以通过创建更多的生产者或消费者来提高应用的吞吐量。
为防止非授权转发,这儿给出本文的原文链接:https://www.cnblogs.com/tiger-wang/p/14068973.html
下面,我们以一个实际例子,来解释这个特性。
创建Channel
Channel提供了一个静态Channel类,提供了两个公开方法来创建两种类型的Channel。
CreateUnbounded - 创建一个具有无限容量的Channel。
CreateBounded - 创建一个具有有限容量的Channel。
人通常来说,这两种方式使用上没有太大的区别。实际应用中,具体要看生产和消费的速度,以及期望产生的结果。有限容量的Channel,容量是有上限的,到达上限后,可以让生产者非阻塞等待消费者使用并释放Channel容量后再继续。这种方式,好处是可以控制生产的速度,控制系统资源的使用,缺点也是。因为控制速度意味着生产速度会被限制,甚至停止。而无限容量,生产者可以全速进行生产。但也有缺点,如果消费者的消费速度低于生产者,Channel的资源使用会无限增加,会有服务器资源耗尽的可能。
今天的例子,我们使用无限Channel。
var channel = Channel.CreateUnbounded<string>();
非常简单的一行代码,就创建了一个无限容量的Channel。
我们定义这个Channel用来保存字符串对象。
创建方法是一个通用的工厂方法,所以我们可以为需要使用的任何类型的对象和数据创建Channel。
Channel有两个属性:阅读器返回ChannelReader,写入器返回ChannelWriter。
写入Channel
使用写入器ChannelWriter,可以对Channel进行写入操作。ChannelWriter提供了以下几个方法:
- WriteAsync - 异步写入
- WaitToWriteAsync - 非阻塞等待,直到有空间可写入时或Channel关闭时,返回true/false
- TryWrite - 尝试写入
- Complete - 标记Channel为关闭,并不再写入数据到该Channel
- TryComplete - 尝试标记Channel为关闭。
这几个方法很容易理解,就不解释了。
在本文的例子里,我用了:
await channel.Writer.WriteAsync("New message");
读取Channel
使用阅读器ChannelReader从Channel进行数据的读取。也提供了几个方法:
- ReadAsync - 异步读取
- ReadAllAsync - 异步读取Channel中的所有数据
- TryRead - 尝试读取
- WaitToReadAsync - 非阻塞等待,直到有数据可读取或Channel关闭时,返回true/false
不同的消费者模式,会用到不同的读取方法。这个根据经验来写就好。
本文的例子中,我是采用WaitToReadAsync和ReadAsync配合来使用的:
while (await ChannelReader.WaitToReadAsync())
{
if (ChannelReader.TryRead(out var timeString))
{
/***/
}
}
WaitToReadAsync是一个非阻塞等待,在有消息可读或Channel关闭时,才会唤醒并继续。
考虑到有多个消费者的情况,有可能别的线程已经进行了读取,这儿使用TryRead进行读取操作。
要注意:数据的同步工作是由Channel进行管理的。Channel会确保多个消费者不会读到相同的数据。Channel同时也管理数据的次序。
示例代码
今天的示例代码我放到了Github上。链接是文章最后。
这个例子中,我做了三个场景。
首先是Channel。我使用了无限Channel。然后是创建生产者和消费者。数据传输过程就简单化了,生产者只简单将一个字符串写入到Channel。消费者也是,简单等待并从Channel读取数据字符串,写入控制台。
三个场景分别是:
单一生产者/单一消费者
这个例子中,创建了一个生产者和一个消费者。两者的任务都是并发启动的。
里面的延时,是用来模拟工作负载的。
多个生产者/单一消费者
这个例子中有两个生产者。通常在应用中有多个生产者时,我们需要确保生产与单个消费者所能处理的消息数量大致相当,这样能更好地利用服务器资源。
单一生产者/多个消费者
这个其实是应用中最常见的情况,就是产生消息很快,但处理工作相关较慢,而且工作也更密集。这种情况,实际应用中我们可以通过扩大消费者数量来满足生产的需求。
总结
最近的项目在做一个大数据的采集,用到了一些Channel的技术。然后发现网上这部分内容很少,就做了个例子,写了这个文章。
Channel内容本身并不多,但用着很方便,而且实际应用中,比想像的更强大。它可以简化很多生产者/消费者模式的使用,而且,任务间交换数据,使用Channel会更方便,更直接。
示例代码在:https://github.com/humornif/Demo-Code/tree/master/0033/demo
微信公众号:老王Plus 扫描二维码,关注个人公众号,可以第一时间得到最新的个人文章和内容推送 本文版权归作者所有,转载请保留此声明和原文链接 |
Dotnet Core下的Channel, 你用了吗?的更多相关文章
- 支付宝AopSdk在dotnet core下的实现
随着项目都迁移到了dotnet core下,阿里的支付宝也需要随着项目迁移.之前在.Net Framework下用到了阿里提供的AopSdk和F2FPay两个程序集,支付宝官方提供的只支持Framew ...
- 【redis】在dotnet core下的redis的使用
1.Install-Package Microsoft.Extensions.Caching.Redis -Version 2.2.0 2.注入 services.AddDistributedRedi ...
- .net core下使用FastHttpApi构建web聊天室
一般在dotnet core下构建使用web服务应用都使用asp.net core,但通过FastHttpApi组建也可以方便地构建web服务应用,在FastHttpApi功能的支持下构建多人聊天室是 ...
- dotnet core高吞吐Http api服务组件FastHttpApi
简介 是dotNet core下基于Beetlex实现的一个高度精简化和高吞吐的HTTP API服务开源组件,它并没有完全实现HTTP SERVER的所有功能,而是只实现了在APP和WEB中提供数据服 ...
- ubuntu15.10 或者 16.04 或者 ElementryOS 下使用 Dotnet Core
这里我们不讲安装,缺少libicu52自行安装. 安装完成后使用dotnet restore或者build都会失败,一是报编译的dll不适合当前系统,二是编译到ubuntu16.04文件夹下会产生一些 ...
- 边缘化搭建 DotNet Core 2.1 自动化构建和部署环境(下)
写在前面 本篇文章是上一篇边缘化搭建 DotNet Core 2.1 自动化发布和部署(上)的后续操作,本文主要讲解如何开启Docker Remote API,开启Remote API后的权限安全问题 ...
- 【Step By Step】将Dotnet Core部署到Docker下
一.使用.Net Core构建WebAPI并访问Docker中的Mysql数据库 这个的过程大概与我之前的文章<尝试.Net Core—使用.Net Core + Entity FrameWor ...
- 解决 dotnet core 1.x 命令行(cli) 下运行路径错误
环境: Windows 10,Visual Studio 2017 centos 7,nginx,supervisor,dotnet core 1.1 问题: 在 Linux 配置 superviso ...
- Linux CentOS 7 下dotnet core webpai + nginx 部署
参考:https://www.jianshu.com/p/b1f573ca50c7 跟着做到,配置nginx访问dotnet core网站时,报错了. 错误如下所示—— 查看nginx的错误日志: c ...
随机推荐
- 云计算之路-出海记:蹭一张 aws 船票
出海记开篇之后,在 aws 上搭建博客园海外站的出海计划今天开始迈出第一步 -- 注册一个 aws 海外区域账号. aws 现在针对新注册用户提供12个月免费套餐(正在园子里推广并提供了专属注册通道) ...
- 企业微信公众号告警Python脚本
#!/usr/bin/env python # -*- coding: utf-8 -*- import time import requests import json import os impo ...
- 蒲公英 · JELLY技术周刊 Vol.28: Next.js 10 发布
蒲公英 · JELLY技术周刊 Vol.28 前端应用到底该选 SSR 还是 CSR?每个项目技术栈决策的时候都会根据实际需求有自己的看法,而在不久前 React 17 发布之后,自然而然也会有同学好 ...
- P5958 【[POI2017]Sabotaż】
P5958 [[POI2017]Sabotaż] 题意描述 在一棵以1号节点为根节点的树上,有很多纯洁的白点, BUT,突然有一个黑点出现(可能在任意位置) 它要染黑尽可能多的节点,而在一棵子树中, ...
- 跟我一起学.NetCore之EF Core 实战入门,一看就会
前言 还记得当初学习数据库操作时,用ADO.NET一步一步地进行数据操作及查询,对于查询到的数据还得对其进行解析,然后封装返回给应用层:遇到这种重复而繁琐的工作,总有一些大神或团队对其进行封装,从而出 ...
- Magicodes.IE 3.0重磅设计畅谈
总体设计 Magicodes.IE导入导出通用库,支持Dto导入导出.模板导出.花式导出以及动态导出,支持Excel.Csv.Word.Pdf和Html. IE在去年年底重构一次之后,经过这么长时间的 ...
- 两个SQL查询,横向合并为一个查询结果
第一条sql: select unit,count(*)as number from archives_management group by unit 第二条sql: select fine_uni ...
- Chrome默认启动尺寸的小问题
记录一个小问题. 这是我的Chrome,他默认启动的时候是这样的: 默认启动的尺寸似乎不可调,网上没有相关资料,简直让强迫症患者无所适从,这里记录一下偶然发现的方法: 调整Chrome的尺寸,选择右上 ...
- Java 最佳命名规则记录
类名:使用双驼峰规则.如 TestService 包名:命名全小写,且使用小写 如使用 web.csvdata.util 而不是 web.csvData.util 或 web.csvdata.util ...
- tp6.0.x 反序列化漏洞
tp6 反序列化漏洞复现 环境 tp6.0 apache php7.3 漏洞分析 反序列化漏洞需要存在 unserialize() 作为触发条件,修改入口文件 app/controller/Index ...