在现代 C# 开发中,C#异步枚举(也称为异步流)是一种强大的特性,它允许我们在不阻塞主线程的情况下逐个获取数据项。这项功能自 C# 8.0 起引入,核心接口是 IAsyncEnumerable<T>。本文将手把手教你如何自定义异步迭代器,即使你是编程小白,也能轻松理解并应用。

IAsyncEnumerable<T> 是 .NET 中用于表示异步可枚举序列的接口。与传统的 IEnumerable<T> 不同,它支持在每次获取下一个元素时执行异步操作(如网络请求、数据库查询等),而不会阻塞调用线程。
使用 await foreach 语句可以遍历 IAsyncEnumerable<T>,这是 C# 8.0 引入的新语法糖。
最简单的自定义 C#异步枚举方式是使用 async IAsyncEnumerable<T> 方法配合 yield return:
using System;using System.Collections.Generic;using System.Threading.Tasks;public static class SimpleAsyncEnumerator{ public static async IAsyncEnumerable<int> CountToFiveAsync() { for (int i = 1; i <= 5; i++) { await Task.Delay(500); // 模拟异步操作 yield return i; } }}// 使用示例public static async Task Main(){ await foreach (var number in SimpleAsyncEnumerator.CountToFiveAsync()) { Console.WriteLine(number); }}这段代码每 500 毫秒输出一个数字,全程不阻塞主线程。这是构建异步流的最常用方式。
有时你需要更精细地控制枚举行为(例如处理取消令牌、资源释放等),这时就需要手动实现 IAsyncEnumerable<T> 和 IAsyncEnumerator<T> 接口。
下面是一个完整的自定义自定义异步迭代器示例:
using System;using System.Collections.Generic;using System.Threading;using System.Threading.Tasks;public class CountdownAsyncEnumerable : IAsyncEnumerable<int>{ private readonly int _start; public CountdownAsyncEnumerable(int start) { _start = start; } public IAsyncEnumerator<int> GetAsyncEnumerator( CancellationToken cancellationToken = default) { return new CountdownAsyncEnumerator(_start, cancellationToken); }}public class CountdownAsyncEnumerator : IAsyncEnumerator<int>{ private int _current; private readonly CancellationToken _cancellationToken; public CountdownAsyncEnumerator(int start, CancellationToken cancellationToken) { _current = start + 1; // 初始值设为 start+1,第一次 MoveNextAsync 会减 1 _cancellationToken = cancellationToken; } public int Current { get; private set; } public async ValueTask<bool> MoveNextAsync() { _cancellationToken.ThrowIfCancellationRequested(); if (_current <= 0) return false; await Task.Delay(300, _cancellationToken); // 模拟异步延迟 _current--; Current = _current; return true; } public ValueTask DisposeAsync() { // 如果有非托管资源或需要异步清理,可在此处处理 return ValueTask.CompletedTask; }}// 使用示例public static async Task Main(){ var cts = new CancellationTokenSource(); cts.CancelAfter(TimeSpan.FromSeconds(2)); // 2 秒后自动取消 try { var countdown = new CountdownAsyncEnumerable(5); await foreach (var num in countdown.WithCancellation(cts.Token)) { Console.WriteLine($"Countdown: {num}"); } } catch (OperationCanceledException) { Console.WriteLine("Countdown was canceled."); }}在这个例子中,我们实现了完整的 IAsyncEnumerable<int> 和 IAsyncEnumerator<int>。注意以下几点:
MoveNextAsync 返回 ValueTask<bool>,表示是否还有下一个元素。CancellationToken,可在异步操作中响应取消请求。.WithCancellation(token) 扩展方法将取消令牌传递给枚举器。大多数情况下,使用 async IAsyncEnumerable<T> + yield return 就足够了。但当你需要:
此时,手动实现 IAsyncEnumerable<T> 和 IAsyncEnumerator<T> 就显得非常有价值。
通过本文,你已经掌握了 C#异步枚举 的两种实现方式:简单场景使用 yield return,复杂场景手动实现接口。无论哪种方式,都能构建高效的异步流,提升应用程序的响应性和性能。
记住关键点:使用 await foreach 遍历,支持取消令牌,合理释放资源。现在,你可以自信地在项目中使用 自定义异步迭代器 了!
本文由主机测评网于2025-12-12发表在主机测评网_免费VPS_免费云服务器_免费独立服务器,如有疑问,请联系我们。
本文链接:https://www.vpshk.cn/2025126441.html