当前位置: 首页 > news >正文

如何在旧版本的 .NET Core / Framework 中使用 C# 8 的异步流(IAsyncDisposable / IAsyncEnumerable / IAsyncEnumerator)

C# 8.0 为我们带来了异步流,可以使用 async foreach,不过使用此语法需要 IAsyncEnumerable / IAsyncEnumerator 类型。本文介绍如何在旧版本的 .NET Framework 和旧版本的 .NET Core 中获得此类型。


本文内容

    • 异步流所需版本
    • 安装 Microsoft.Bcl.AsyncInterfaces
    • 使用异步流
      • 定义支持异步流的方法
      • 使用 await foreach
    • 额外说明

异步流所需版本

异步流需要 .NET Core 3.0 及以上版本才能直接支持。而如果是 .NET Framework,则是任何版本都不直接支持。

如果需要在早期版本使用异步流,需要安装 Microsoft.Bcl.AsyncInterfaces 这个 NuGet 包。这就像在早期版本中使用 ValueTuple 需要安装 System.ValueTuple 一样。

安装 Microsoft.Bcl.AsyncInterfaces

需要先在你的项目中安装 NuGet 包:

Microsoft.Bcl.AsyncInterfaces

<PackageReference Include="Microsoft.Bcl.AsyncInterfaces" Version="1.1.0" />

安装此包之后,即可在你的项目当中开启异步流的支持。

一点说明:异步流中使用到了 ValueTask,此类型需要 System.Threading.Tasks.Extensions 包的支持。在 .NET Framework 4.8 以下会自动额外引入此包。

使用异步流

定义支持异步流的方法

private async IAsyncEnumerable<string> EnumerateTestsAsync()
{
    for (var i = 0; i < 3; i++)
    {
        await Task.Delay(100).ConfigureAwait(false);
        yield return $"欢迎访问吕毅的博客,第 {i} 页";
    }
}

使用 await foreach

直接使用 await foreach 即可使用 C# 8.0 带来的异步流。

var verify = 0;
await foreach (var i in EnumerateTestsAsync())
{
    Assert.AreEqual(verify, i);
    verify++;
}
Assert.AreEqual(3, verify);

额外说明

记得如果你在 .NET Framework 4.8 或以下版本,.NET Core 3.0 以下版本编写代码时,自动启用的 C# 语言版本是 7.3,所以你需要额外为你的项目启用 C# 8.0 才行。

<LangVersion>latest</LangVersion>

另外,由于 ValueTask 要求的最低 .NET Framework 版本为 4.5.2,所以如果使用更低版本的 .NET Framework,将无法使用异步流。


参考资料

  • Async streams - C# 8.0 specification proposals - Microsoft Docs
  • Using async disposable and async enumerable in frameworks older than .NET Core 3.0 - StrathWeb. A free flowing web tech monologue.

我的博客会首发于 https://blog.walterlv.com/,而 CSDN 会从其中精选发布,但是一旦发布了就很少更新。

如果在博客看到有任何不懂的内容,欢迎交流。我搭建了 dotnet 职业技术学院 欢迎大家加入。

知识共享许可协议

本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。欢迎转载、使用、重新发布,但务必保留文章署名吕毅(包含链接:https://walterlv.blog.csdn.net/),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请与我联系。

相关文章:

  • .NET/C# 解压 Zip 文件时出现异常:System.IO.InvalidDataException: 找不到中央目录结尾记录。
  • 为什么实现 .NET 的 ICollection 集合时需要实现 SyncRoot 属性?如何正确实现这个属性?
  • 为什么不应该公开用来同步的加锁对象?为什么不应该 lock(this)/lock(string) 或者 lock 任何非私有对象?
  • WPF 中如何创建忽略 DPI 属性的图片
  • .NET 中选择合适的文件打开模式(CreateNew, Create, Open, OpenOrCreate, Truncate, Append)
  • Win32 方法 CreateFile 中选择合适的文件打开模式(CREATE_NEW, CREATE_ALWAYS, OPEN_EXISTING, OPEN_ALWAYS, TRUNCATE_EXI
  • 使用 Kestrel 为你的 ASP.NET Core 服务添加 https 支持
  • 三种方法为 ASP.NET Core 对外服务添加 https 支持(kestrel / frp / nginx)
  • 为 ASP.NET Core 程序制作 URL 的 301/302 跳转
  • 使用 Frp 为你的 Web 服务添加 https 支持
  • 全民 https!使用 FreeSSL 申请免费的 https 证书
  • 如何设置 ASP.NET Core 程序监听的 IP 和端口
  • 收集的 Linux VPS 在线重装系统脚本
  • Linux 系统根目录下的文件夹
  • 修复 Windows 10 设置界面里面混乱的语言翻译
  • Android交互
  • Docker 1.12实践:Docker Service、Stack与分布式应用捆绑包
  • Docker 笔记(1):介绍、镜像、容器及其基本操作
  • iOS筛选菜单、分段选择器、导航栏、悬浮窗、转场动画、启动视频等源码
  • UEditor初始化失败(实例已存在,但视图未渲染出来,单页化)
  • Vue.js-Day01
  • 半理解系列--Promise的进化史
  • 分享一个自己写的基于canvas的原生js图片爆炸插件
  • 普通函数和构造函数的区别
  • 前端攻城师
  • 为视图添加丝滑的水波纹
  • 一份游戏开发学习路线
  • 中文输入法与React文本输入框的问题与解决方案
  • d²y/dx²; 偏导数问题 请问f1 f2是什么意思
  • ​香农与信息论三大定律
  • (14)目标检测_SSD训练代码基于pytorch搭建代码
  • (20050108)又读《平凡的世界》
  • (k8s中)docker netty OOM问题记录
  • (PWM呼吸灯)合泰开发板HT66F2390-----点灯大师
  • (Redis使用系列) Springboot 使用Redis+Session实现Session共享 ,简单的单点登录 五
  • (翻译)terry crowley: 写给程序员
  • (附源码)springboot工单管理系统 毕业设计 964158
  • (附源码)springboot金融新闻信息服务系统 毕业设计651450
  • (附源码)计算机毕业设计SSM在线影视购票系统
  • (顺序)容器的好伴侣 --- 容器适配器
  • (未解决)macOS matplotlib 中文是方框
  • (转)关于pipe()的详细解析
  • (转)甲方乙方——赵民谈找工作
  • .mysql secret在哪_MySQL如何使用索引
  • .Net Core和.Net Standard直观理解
  • .NET Core日志内容详解,详解不同日志级别的区别和有关日志记录的实用工具和第三方库详解与示例
  • .net 程序 换成 java,NET程序员如何转行为J2EE之java基础上(9)
  • .net 发送邮件
  • .net经典笔试题
  • .Net开发笔记(二十)创建一个需要授权的第三方组件
  • .net连接MySQL的方法
  • /bin、/sbin、/usr/bin、/usr/sbin
  • @EventListener注解使用说明
  • @reference注解_Dubbo配置参考手册之dubbo:reference
  • [AI]文心一言爆火的同时,ChatGPT带来了这么多的开源项目你了解吗