C#8.0宝藏好物Async streams

之前写《.NET gRPC 核心功能初体验》,利用gRPC双向流做了一个打乒乓的Demo,存储消息的对象是IAsyncEnumerable<T>,这个异步可枚举泛型接口支撑了gRPC的实时流式通信。

本文我将回顾分享

  • foreach/yield return/async await语法糖的本质

  • 如何使用异步流

  • 附加探索: 编写一个更有意义的迭代效果

foreach/ yield return/async await的本质

.NET诞生之初,就通过IEnumerable、IEnumerator提供迭代能力, 前者代表具备可枚举的性质,后者代表可被枚举的方式。
(看你骨骼惊奇,再送你一本《2021年了,IEnumerableIEnumerator接口还傻傻分不清楚?》)
如果你真的使用强类型IEnumerable/IEnumerator来产生/消费可枚举类型,会发现要写很多琐碎代码。

C#推出的yield return迭代器语法糖,简化了产生可枚举类型的编写过程。(编译器将yield return转换为状态机代码来实现IEnumerable,IEnumerator)

yield 关键字可以执行状态迭代,并逐个返回枚举元素,在返回数据时,无需创建临时集合来存储数据。

C#foreach语法糖,简化了消费可枚举类型的编写过程。(编译器将foreach抓换为强类型的方法/属性调用)

IEnumerable src = ...;
IEnumerator e = src.GetEnumerator();
try
{while (e.MoveNext()) Use(e.Current);
}
finally { if (e != null) e.Dispose(); }

NET Framework4引入Task,.NET Framework 4.5/C#5.0引入了await/async异步编程语法糖,简化了异步的编写过程。(编译器将await/async语法糖转换为状态机,产生Task并在内部回调)

☺️以上也看出微软为帮助我们更快速优雅地编写代码,给了很多糖,编译器做了很多事情。

C#提供了迭代、异步的快捷方式,能否将两者结合?
两者结合的效果就是:我们希望在数据就绪时,接收并处理数据,但不会以阻塞cpu的形式等待,这在lot流式数据中很常见。

异步迭代

有一只爬虫要通过列表页上的链接,抓取链接背后的html内容并显示。这是一个[相互独立的长耗时行为的集合(假设分别耗时5,4,3,2,1s)],
我们使用C#8.0异步可枚举类型IAsyncEnumerable,异步 产生/消费枚举元素。

与同步版本IEmunerable类似,IAsyncEnumerable也有对应的IAsyncEnumerator迭代器,迭代器的实现过程决定了foreach消费的顺序。

C#8.0  Asynchronous streams

C#8.0中一个重要的特性是异步流(async stream), 可以轻松创建和消费异步枚举。

返回异步流的方法特征:

  • async修饰符声明

  • 返回IAsyncEnumerable<T>对象

  • 方法包含yield return语句,用来异步持续返回元素

static async Task Main(string[] args)
{Console.WriteLine(DateTime.Now + $"\tThreadId:{Thread.CurrentThread.ManagedThreadId}\r\n");await foreach (var html in FetchAllHtml()){Console.WriteLine(DateTime.Now + $"\tThreadId:{Thread.CurrentThread.ManagedThreadId}\t" + $"\toutput:{html}");}Console.WriteLine("\r\n" + DateTime.Now + $"\tThreadId:{Thread.CurrentThread.ManagedThreadId}\t");Console.ReadKey();}static async IAsyncEnumerable<string> FetchAllHtml(){for (int i = 5; i >= 1; i--){var html = await Task.Delay(i* 1000).ContinueWith((t,i)=> $"html{i}",i);    //  模拟长耗时yield return html;}}

for循环结合yield关键字,决定了IAsyncEnumerator的实现;
以上代码将使得await foreach消费异步枚举时, 采用与for循环一样的顺序,也就是产生异步任务的先后顺序以上不会等待15s然后一股脑抛出所有数据, 而是根据枚举for循环  依次就绪,依次显示,总共还是耗时15s,每一次枚举都是异步的。

附加思考:产生一个有意思的迭代器

☺️ 但是我内心想,能不能按照完成异步任务的顺序,先完成先消费,这难道不是人之常情,交互体验应该更好。

static async IAsyncEnumerable<string> FetchAllHtml()
{  var tasklist= new List<Task<string>>();for (int i = 5; i >= 1; i--){var t= Task.Delay(i* 1000).ContinueWith((t,i)=>$"html{i}",i);      // 模拟长耗时任务tasklist.Add(t);}while(tasklist.Any())  {var tFinlish = await Task.WhenAny(tasklist);tasklist.Remove(tFinlish); yield return await tFinlish;}
}  

上面我先构造了可等待的任务列表,通过Task.WhenAny() 返回异步任务先完成的迭代元素。  

以上总耗时取决于 耗时最长的那个枚举任务:5s

.NETCore 3.1 已经可以在webapi中使用异步流,意味着我们可将流式数据返回到HTTP响应。

前端也已经有试验性的Streams API可以消费流式数据。

传送门:   https://developer.mozilla.org/en-US/docs/Web/API/Streams_API
浏览器兼容列表:    https://developer.mozilla.org/en-US/docs/Web/API/Streams_API#browser_compatibility

对于web应用,这着实能提高 可交互性:
想象之前含多个长耗时行为的列表数据,现在不必等待所有数据,配以loading,谁先完成谁加载,效果杠杠。

# 更多精彩

  • .NET gRPC核心功能初体验

  • 2021年了,`IEnumerator`、`IEnumerable`接口还傻傻分不清楚?

  • 实话实说:只会.NET,会让我们一直处于鄙视链、食物链的下游

  • 鹅厂二面,Nginx回忆录

  • .NET微服务最佳实践eShopOnContainers

原创不易 点个在看支持下~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/303582.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

连接mysql数据库2013_使用VS2013 + EF6 + .NET4.5 连接Mysql数据库

1、安装插件在使用Visual Studio 2013添加ADO.NET实体数据模型新建连接时&#xff0c;默认是没有Mysql选项的。此时我们需要安装两个东西&#xff1a;1、mysql-for-visualstudio&#xff1a;Mysql的Visual Studio插件&#xff0c;推荐1.2.3版本2、mysql-connector-net&#xff…

重磅来袭,2018 年 6 月编程语言排行榜

TIOBE 编程语言社区最新发布了 2018 年 6 月排行榜&#xff0c;和 5 月榜单相比&#xff0c;前九名没有任何变化&#xff0c;依然是 Java、C、C、Python、C#、Visual Basic .NET、PHP、JavaScript、SQL。5月份第十名的Ruby在这个月下降了一名&#xff0c;而R则上升一名&#xf…

mysql bench linux_MySQL Study之--Linux下安装MySQL workbench工具

系统环境&#xff1a;操作系统&#xff1a; RedHat EL6.4(64)WorkBench&#xff1a; mysql-workbench-community-6.0.9MySQL Workbench是一款专为MySQL设计的ER/数据库建模工具。它是著名的数据库设计工具DBDesigner4的继任者。你可以用MySQL Workbench设计和创建新的数据库图示…

.NET6发布了Preview2,这点超越过去10年!

从ASP.NET的性能诟病&#xff0c;到.NET Core的性能持续改进&#xff0c;在每一个.NET Core版本都能看到性能优化提升的介绍。.NET Core3.1在各种性能排行中霸榜&#xff0c;.NET5再度提升了性能&#xff0c;前些天发布的.NET Preview2&#xff0c;通过PGO &#xff08;Profile…

人工智能预测2018年世界杯 | 德国人打破历史将在俄罗斯上取得最后的胜利?

2018年俄罗斯世界杯近在眼前&#xff0c;比赛将于6月14日~7月15日在俄罗斯的各地举行。但世界杯还没开始&#xff0c;人们已经出现了各种各样的“比赛结果预测”。其中不乏有一些专业人士以及原足球选手&#xff0c;也有许多“生物”对此预测。前几年&#xff0c;章鱼哥保罗就准…

Q+开放的互联网:腾讯QQ “亮剑” 开放平台

&#xff08;图一&#xff09; 近日&#xff0c;人民日报的腾讯广告&#xff08;图一&#xff09;&#xff0c;在网民心中引起不小的波动。看着图中憨厚的小企鹅&#xff0c;后面是数以万计的应用软件&#xff0c;给人一种大将领兵征战沙场的感觉。图片左下角是 “Q开放的互联网…

php查询mysql乱码_php 查询mysql乱码怎么办

php查询mysql乱码的解决办法&#xff1a;1、修改PHP页面语言本身的编码类型&#xff1b;2、将MySQL字符集更改为“UTF8”&#xff1b;3、使用ultraplus中的编码转换功能进行转换。php读取mysql中文数据出现乱码的解决方法1.PHP页面语言本身的编码类型不合适&#xff0c;这时候&…

猝不及防,Google成功“造人”令人胆寒!人类迎来史上最惨失业潮…

01猝不及防&#xff01;这次&#xff0c;Google“造人”了&#xff01;5月8号&#xff0c;谷歌召开一年一度的Google I/O大会。谷歌CEO劈柴直接祭出了这次大会的王牌AI&#xff0c;这个智能过人的Al让人看完不禁倒吸一口凉气……相比Apple Siri和Microsoft Cortana只能机械式对…

雷军这个程序员!真的牛逼!

阅读本文大概需要3分钟。这两天忙着给CEO汇报工作以及跟进几个新产品的进展&#xff0c;忙到连新闻都没时间看。今天终于轻松了点&#xff0c;早上起来刷了刷知乎&#xff0c;看见一个让我惊呆了的消息&#xff1a;雷军要造车了&#xff01;雷军宣称亲自带队&#xff0c;初期就…

poj2545

题意&#xff1a;给出三个质数&#xff0c;求这素因子只有这三个质数的数中第k大的。 分析&#xff1a;用一个数列&#xff0c;第一位是1。用三个指针指向三个prime要乘的被乘数&#xff0c;最开始都指向1。每次取乘积最小的加入数组&#xff0c;并把指针后移。加入时要判断是否…

微软发布 Windows 10 预览版 Build 21343:此电脑和回收站等启用全新图标

微软已向开发频道&#xff08;Dev&#xff09;的 Windows 预览体验成员发布了 Windows 10 Insider Preview Build 21343 更新。内置应用和文件夹启用全新图标从去年开始&#xff0c;微软就不断为 Windows 10 内置应用重新设计图标。在 Windows 10 版本 20H2 更新中&#xff0c;…

什么样的程序员会让人讨厌

我有一个朋友&#xff0c;就是一个程序员&#xff0c;找他做事的时候&#xff0c;最让人讨厌了。00不愿意帮我修电脑。我说电脑坏了&#xff0c;想让他看看&#xff0c;他先是叫我检查插头&#xff0c;然后叫我重启&#xff0c;重启好之后&#xff0c;他冷淡的说&#xff1a;以…

金州勇士队,硅谷黑科技打造的NBA奇迹!

【导读&#xff1a;2018NBA决赛表明&#xff0c;创业如同打球&#xff0c;应该学习勇士&#xff0c;团队作战打“群架”&#xff0c;单打独斗像骑士&#xff0c;纵有“小皇帝”&#xff0c;也难免被横扫】NBA是中国人民最喜欢观看和讨论的美国体育联赛。在NBA诸强中&#xff0c…

入坑机器学习?送你一篇麻省博士的学习心得

[导读] 随着人工智能技术的火热&#xff0c;越来越多的年轻学者正准备投身其中&#xff0c;开启自己的研究之路。和所有其他学科一样&#xff0c;人工智能领域的新人总会遇到各种各样的难题&#xff0c;其中不仅有研究上的&#xff0c;也有生活方面的。MIT EECS 在读博士、前 V…

C# 读写Ini文件

ini文件在Win95以前比较盛行&#xff0c;之后由于出册表等技术的出现&#xff0c;ini技术主键退居二线&#xff0c;不过对于一些小项目&#xff0c;读写ini文件还是很适用的。Windows API提供了读写配置文件的操作&#xff0c;在C#程序中只要导入相应的API即可。例如GetPrivate…

更改windows2003远程最大连接数

windows 2003中的远程桌面功能非常方便&#xff0c;但是初始设置只允许2个用户同时登陆。有些时候因为我在公司连接登陆后断开&#xff0c;同事在家里用其他用户登陆后断开&#xff0c;当我再进行连接的时候&#xff0c;总是报错终端服务超过最大连接数。这时候我和同事都不能登…

mysql sp who_对ASE系统存储过程的剖析-sp_who

昨晚有空&#xff0c;把 sybase 系统过程 sp_who &#xff0c; DDL 后分析了一下&#xff0c;全文如下&#xff1a;-- 以下是 DDL 出来的内容&#xff1a;------------------------------------------------------------------------------- DDL for Stored procedure sybsyste…

区块链、自动驾驶、人工智能鏖战开始 谁将成为下一个风口?

近年来&#xff0c;区块链、自动驾驶以及人工智能的概念频繁爆红于科技界。有业者称&#xff0c;区块链的颠覆在于人们找到了一个低成本解决信任问题的方案&#xff1b;自动驾驶的出现方便了人们的交通出行&#xff1b;人工智能则为我们打开了新的世界。不论是区块链、自动驾驶…

JWT 介绍 - Step by Step

翻译自 Mohamad Lawand 2021年3月11日的文章 《Intro to JWT - Step by Step》 [1]在本文中&#xff0c;我将向您介绍 JWT[2]。我们今天要讲的内容包含&#xff1a;JWT 是什么我们应该在什么时候使用它JWT 与 Session Id 比较JWT 结构JWT 签名JWT 是什么JWT (JSON Web Token) 是…

Helpdesk 流程

最近Fox的公司部署了新的Helpdesk系统。为了让用户从原来打电话和发邮件寻求IT员工帮助的方式转变为使用Helpdesk系统提交tickets&#xff0c;需要制定和规范Helpdesk流程&#xff0c;小小推动下ITIL进程。 HelpDesk系统与AD集成。公司用户可以使用域用户名和密码登陆Helpdesk系…