.NET Core 3.0中IAsyncEnumerableT有什么大不了的?
.NET Core 3.0和C# 8.0最激动人心的特性之一就是IAsyncEnumerable<T>(也就是async流)。但它有什么特别之处呢?我们现在可以用它做哪些以前不可能做到的事?
在本文中,我们将了解IAsyncEnumerable<T>要解决哪些挑战,如何在我们自己的应用程序中实现它,以及为什么IAsyncEnumerable<T>将在很多情况下取代Task<IEnumerable<T>>。
也许最好的证明IAsyncEnumerable < T >有用的方式是看看在没有它的时候所面临的的困难。
比如首先有这样一段代码,按页面获取所有喜欢的帖子:
public async Task<IEnumerable<Post>> GetPagePostsFromLikes(int pageNumber) {// 实现省略 }
然后有另一段代码调用上面这段代码:
public async Task<IEnumerable<Post>> GetAllPostsFromLikes() {var allPosts = new List<Post>(); for (int page = 0; ; page++) {var posts = await GetPagePostsFromLikes(page);if (!posts.Any()) {return allPosts; } allPosts.AddRange(posts); } }
注意,上面这个方法有一个问题,我们对每个页面的结果进行循环并放入List<Post>中,最后返回整个结果。假设有上亿个page页面的的帖子,那么所有这上亿个page页面的帖子都需要在返回值之前被加载。显然是非常低效的。
也许我们可以不使用Task来替换上面的方法:
public IEnumerable<Post> GetAllPostsFromLikes() {for (int page = 0; ; page++) {var posts = GetPagePostsFromLikes(page).GetAwaiter().GetResult();if (!posts.Any()) {yield break; }foreach (var post in posts) {yield return post; } } }
在上面代码中,返回IEnumerable<T>的方法可以使用yield return语句将每个数据片段返回给调用者。
但是,请勿这样做! 上面的代码意味着如果我们从异步方法中调用第三个函数,线程池将持续迭代返回的IEnumerable,直到其完成,也就是说当有足够多的并发访问同一个线程,势必会造成阻塞。
如果我们可以用异步方法来使用yield return就好了!可惜那是不可能的……直到现在。
这个时候IAsyncEnumerable<T> 就该出场啦!!!!!!
IAsyncEnumerable<T>是在.NET Core 3 (.NET Standard 2.1)引入的。它公开了一个枚举器,该枚举器具有可以等待的MoveNextAsync()方法。这意味着生产者可以在产生结果之间进行异步调用。
与返回任务<IEnumerable<T>>不同,我们的方法现在可以返回IAsyncEnumerable<T>,并使用yield return来发送数据:
public async IAsyncEnumerable<Post> GetAllPostsFromLikes() {for (int page = 0; ; page++) {var posts = GetPagePostsFromLikes(page).GetAwaiter().GetResult();if (!posts.Any()) {yield break; }foreach (var post in posts) {yield return post; } } }
为了使用结果,我们需要使用c# 8中新的await foreach()语法:
await foreach (var post in postsRepository.GetAllPostsFromLikes()) { Console.WriteLine(post); }
这个好多了。该方法生成可用的数据。调用代码以自己的节奏使用数据。
从.NET Core 3.0 Preview 7 开始,ASP.NET就能够从API控制器动作中返回IAsyncEnumerable<T>,这意味着我们可以直接返回方法的结果——有效地将数据从数据库流到HTTP响应。
[HttpGet]public IAsyncEnumerable<Post> Get()=> postsRepository.GetAllPostsFromLikes();
随着时间的推移,随着.NET Core3.0和.NET Standard2.1的发展,我们将会看到IAsyncEnumerable<T>被用在我们通常使用Task<IEnumerable<T>>的地方。
总结
IAsyncEnumerable<T>是. net的一个很受欢迎的新特性,在很多情况下,它可以使代码更简洁、更高效。
想要了解更多,请参考以下资源:
Tutorial: Generate and consume async streams using C# 8.0 and .NET Core 3.0
C# language proposals - Async Streams
new features in .NET Core 3
.NET Core 3.0中IAsyncEnumerableT有什么大不了的?相关推荐
- ASP.NET Core 3.0中使用动态控制器路由
原文:Dynamic controller routing in ASP.NET Core 3.0 作者:Filip W 译文:https://www.cnblogs.com/lwqlun/p/114 ...
- .NET Core 3.0中的数据库驱动框架System.Data
虽然没有得到很多关注,但System.Data对于.NET中任何关系型数据库的访问都至关重要.因为其前身是ActiveX Data Objects,所以它也被称为ADO.NET.System.Data ...
- .NET Core 3.0 中的新变化
译者:楚人Leo 译文:http://www.cnblogs.com/leolion/p/10585834.html 原文:https://msdn.microsoft.com/en-us/magaz ...
- 避免在 ASP.NET Core 3.0 中为启动类注入服务
本篇是如何升级到ASP.NET Core 3.0系列文章的第二篇. Part 1 - 将.NET Standard 2.0 类库转换为.NET Core 3.0 类库 Part 2 - IHostin ...
- IHostingEnvironment VS IHostEnvironment - .NET Core 3.0中的废弃类型
原文:https://andrewlock.net/ihostingenvironment-vs-ihost-environment-obsolete-types-in-net-core-3/ 作者: ...
- 在.Net Core 3.0中尝试新的System.Text.Json API
.NET Core 3.0提供了一个名为System.Text.Json的全新命名空间,它支持reader/writer,文档对象模型(DOM)和序列化程序.在此博客文章中,我将介绍它如何工作以及如何 ...
- asp.net core 3.0 中使用 swagger
asp.net core 3.0 中使用 swagger Intro 上次更新了 asp.net core 3.0 简单的记录了一下 swagger 的使用,那个项目的 api 比较简单,都是匿名接口 ...
- .NET Core 3.0 中的数据库驱动框架 System.Data
虽然没有得到很多关注,但System.Data对于.NET 中任何关系型数据库的访问都至关重要.因为其前身是 ActiveX Data Objects,所以它也被称为 ADO.NET.System.D ...
- ASP.Net Core 2.0中的Razor Page不是WebForm
随着.net core2.0的发布,我们可以创建2.0的web应用了.2.0中新东西的出现,会让我们忘记老的东西,他就是Razor Page.下面的这篇博客将会介绍ASP.Net Core 2.0中的 ...
最新文章
- 指针02 - 零基础入门学习C语言42
- gcc -ldl 选项作用
- 阿里巴巴成立首个IoT生态联盟 将打通技术标准
- android listview 异步加载问题
- 如何使用TensorFlow玩转深度学习?
- java 指向同一地址,Sring a和String b的值相同,是不是指向同一个地址呢
- css sprite 介绍和实例
- 逐句深扒 Apache 许可协议原文,一文看懂!
- Eclipse 取消 Import 堆叠
- Linux笔记(一)——虚拟机的安装与Centors安装,安装vmtools,虚拟机的克隆,虚拟机的快照,共享文件的使用
- java反编译数组_JavaGuide/JAD反编译tricks.md at master · Github-Programer/JavaGuide · GitHub...
- web前端开发面试题(六)
- 抖音短视频的用户来源和活跃时间
- 计算机在职研究生是学历教育吗,计算机在职研究生有学籍吗
- 固态硬盘跟机械硬盘的区别
- Bugku_隐写 [Study notes][MISC]
- LLVM系列(三)小插曲---Clang的常用命令
- 关于铅酸蓄电池的充放电实验以及安装调试
- 触摸IC TTP229学习笔记
- 每天一点儿时间学习Spring框架系列—IOC(2)