.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有什么大不了的?相关推荐

  1. ASP.NET Core 3.0中使用动态控制器路由

    原文:Dynamic controller routing in ASP.NET Core 3.0 作者:Filip W 译文:https://www.cnblogs.com/lwqlun/p/114 ...

  2. .NET Core 3.0中的数据库驱动框架System.Data

    虽然没有得到很多关注,但System.Data对于.NET中任何关系型数据库的访问都至关重要.因为其前身是ActiveX Data Objects,所以它也被称为ADO.NET.System.Data ...

  3. .NET Core 3.0 中的新变化

    译者:楚人Leo 译文:http://www.cnblogs.com/leolion/p/10585834.html 原文:https://msdn.microsoft.com/en-us/magaz ...

  4. 避免在 ASP.NET Core 3.0 中为启动类注入服务

    本篇是如何升级到ASP.NET Core 3.0系列文章的第二篇. Part 1 - 将.NET Standard 2.0 类库转换为.NET Core 3.0 类库 Part 2 - IHostin ...

  5. IHostingEnvironment VS IHostEnvironment - .NET Core 3.0中的废弃类型

    原文:https://andrewlock.net/ihostingenvironment-vs-ihost-environment-obsolete-types-in-net-core-3/ 作者: ...

  6. 在.Net Core 3.0中尝试新的System.Text.Json API

    .NET Core 3.0提供了一个名为System.Text.Json的全新命名空间,它支持reader/writer,文档对象模型(DOM)和序列化程序.在此博客文章中,我将介绍它如何工作以及如何 ...

  7. asp.net core 3.0 中使用 swagger

    asp.net core 3.0 中使用 swagger Intro 上次更新了 asp.net core 3.0 简单的记录了一下 swagger 的使用,那个项目的 api 比较简单,都是匿名接口 ...

  8. .NET Core 3.0 中的数据库驱动框架 System.Data

    虽然没有得到很多关注,但System.Data对于.NET 中任何关系型数据库的访问都至关重要.因为其前身是 ActiveX Data Objects,所以它也被称为 ADO.NET.System.D ...

  9. ASP.Net Core 2.0中的Razor Page不是WebForm

    随着.net core2.0的发布,我们可以创建2.0的web应用了.2.0中新东西的出现,会让我们忘记老的东西,他就是Razor Page.下面的这篇博客将会介绍ASP.Net Core 2.0中的 ...

最新文章

  1. 指针02 - 零基础入门学习C语言42
  2. gcc -ldl 选项作用
  3. 阿里巴巴成立首个IoT生态联盟 将打通技术标准
  4. android listview 异步加载问题
  5. 如何使用TensorFlow玩转深度学习?
  6. java 指向同一地址,Sring a和String b的值相同,是不是指向同一个地址呢
  7. css sprite 介绍和实例
  8. 逐句深扒 Apache 许可协议原文,一文看懂!
  9. Eclipse 取消 Import 堆叠
  10. Linux笔记(一)——虚拟机的安装与Centors安装,安装vmtools,虚拟机的克隆,虚拟机的快照,共享文件的使用
  11. java反编译数组_JavaGuide/JAD反编译tricks.md at master · Github-Programer/JavaGuide · GitHub...
  12. web前端开发面试题(六)
  13. 抖音短视频的用户来源和活跃时间
  14. 计算机在职研究生是学历教育吗,计算机在职研究生有学籍吗
  15. 固态硬盘跟机械硬盘的区别
  16. Bugku_隐写 [Study notes][MISC]
  17. LLVM系列(三)小插曲---Clang的常用命令
  18. 关于铅酸蓄电池的充放电实验以及安装调试
  19. 触摸IC TTP229学习笔记
  20. 每天一点儿时间学习Spring框架系列—IOC(2)

热门文章

  1. WCF发布到IIS7问题的解决方案
  2. .text 0.958之间居的中文汉化下载
  3. 如何在PowerPoint中自动调整图片大小
  4. vue引入全局less实现全局变量的控制
  5. 10以内数的组成分解图_大班数学教案《10以内数的组成》
  6. Vue根据菜单json数据动态按需加载路由Vue-router
  7. python assert的作用
  8. JAVA配置Tomcat
  9. js 中声明变量 “提前”
  10. 【C#语言规范】从FxCop归纳出来的一些规范建议