You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将C# .NET 6中的IEnumerable方法转换为异步方法

将同步迭代器方法改造为异步方法(.NET 6)

1. 改造getUsersFor为异步迭代器方法

  • 返回类型从IEnumerable<User>改为IAsyncEnumerable<User>,这是.NET中异步迭代器的标准返回类型
  • 方法名遵循异步命名规范改为GetUsersForAsync
  • 添加async修饰符
  • 将原代码中阻塞线程的.Result替换为await,适配异步调用逻辑
  • 保留yield return语法,异步迭代器原生支持该写法

改造后代码:

public async IAsyncEnumerable<User> GetUsersForAsync(string accountId)
{
    ListUsersResponse usersResponse;
    string marker = null;
    do
    {
        using (var myClient = new ServiceClient(pass))
        {
            usersResponse = await myClient.ListUsersAsync(
                new ListUsersRequest { Marker = marker, MaxItems = MAX_ITEMS });
            foreach (var user in usersResponse.Users)
            {
                yield return user;
            }
        }

        marker = usersResponse.Marker;
    } while (usersResponse.IsTruncated);
}

2. 改造getUsers为异步方法

  • 返回类型改为IAsyncEnumerable<MyUser>,方法名改为GetUsersAsync
  • 添加async修饰符
  • 由于同步LINQ的SelectMany不支持异步枚举,提供两种实现方式:

方式一:手动遍历异步枚举(无需额外依赖)

通过await foreach逐个处理每个账号的用户集合,异常时跳过当前账号:

public async IAsyncEnumerable<MyUser> GetUsersAsync()
{
    foreach (var accountId in AccountById.Keys)
    {
        try
        {
            await foreach (var user in GetUsersForAsync(accountId))
            {
                yield return new MyUser(user,
                    SetAccountUniqueName(AccountById[accountId].Name,
                        AccountById[accountId].Id));
            }
        }
        catch (Exception ex)
        {
            _log.Error(ex);
        }
    }
}

方式二:使用LINQ Async扩展(需安装NuGet包)

若想保持类原LINQ的简洁写法,可安装System.Linq.Async NuGet包,使用异步LINQ扩展方法:

using System.Linq;

public async IAsyncEnumerable<MyUser> GetUsersAsync()
{
    return AccountById.Keys
        .SelectManyAsync(async accountId =>
        {
            try
            {
                return await GetUsersForAsync(accountId)
                    .Select(user => new MyUser(user,
                        SetAccountUniqueName(AccountById[accountId].Name,
                            AccountById[accountId].Id)))
                    .ToListAsync();
            }
            catch (Exception ex)
            {
                _log.Error(ex);
                return Enumerable.Empty<MyUser>();
            }
        });
}

调用注意事项

异步迭代器方法需要用await foreach遍历结果,示例:

await foreach (var myUser in GetUsersAsync())
{
    // 处理用户逻辑
}
  • 禁止在异步方法中使用.Result或.Wait(),避免线程阻塞和死锁风险
  • 添加Async后缀是.NET异步方法的命名规范,提升代码可读性

内容的提问来源于stack exchange,提问作者Amir M

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 15:47:08