C# 8.0 为我们带来了异步流,可以使用 async foreach
,不过使用此语法需要 IAsyncEnumerable
/ IAsyncEnumerator
类型。本文介绍如何在旧版本的 .NET Framework 和旧版本的 .NET Core 中获得此类型。
异步流所需版本
异步流需要 .NET Core 3.0 及以上版本才能直接支持。而如果是 .NET Framework,则是任何版本都不直接支持。
如果需要在早期版本使用异步流,需要安装 Microsoft.Bcl.AsyncInterfaces 这个 NuGet 包。这就像在早期版本中使用 ValueTuple
需要安装 System.ValueTuple 一样。
安装 Microsoft.Bcl.AsyncInterfaces
需要先在你的项目中安装 NuGet 包:
1
<PackageReference Include="Microsoft.Bcl.AsyncInterfaces" Version="1.1.0" />
安装此包之后,即可在你的项目当中开启异步流的支持。
一点说明:异步流中使用到了 ValueTask
,此类型需要 System.Threading.Tasks.Extensions 包的支持。在 .NET Framework 4.8 以下会自动额外引入此包。
使用异步流
定义支持异步流的方法
1
2
3
4
5
6
7
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 带来的异步流。
1
2
3
4
5
6
7
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 才行。
1
<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/post/use-async-streams-in-old-dotnet.html ,以避免陈旧错误知识的误导,同时有更好的阅读体验。
本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。欢迎转载、使用、重新发布,但务必保留文章署名 吕毅 (包含链接: https://blog.walterlv.com ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请 与我联系 ([email protected]) 。