Enumerable.SelectMany 抛出错误 CS0411 - 无法从用法推断

问题描述 投票:0回答:1

我正在使用c#,.net 6.0

我正在尝试将 IEnumerable 方法和 ot 的调用者方法转换为异步工作。

我有一个看起来像这样的代码:

    public IEnumerable<MyUser> getUsers()
{
    return AccountById
        .Keys
        .SelectMany(accountId => {
            try
            {
                return getUsersFor(accountId)
                    .Select(x => new MyUser(x,
                        SetAccountUniqueName(AccountById[accountId].Name,
                            AccountById[accountId].Id)));
            }
            catch (Exception ex)
            {
                _log.Error(ex);
                return Enumerable.Empty<MyUser>();
            }
        });
}

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

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

我将 getUsers() 和 getUsersFor() 转换为异步工作。

我尝试了这段代码:

    public async Task<List<MyUser>> GetUsersAsync()
    {
        return await AccountById
            .Keys
            .SelectMany(async accountId =>
            {
                try
                {
                    await foreach (var user in GetUsersForAsync(accountId))
                    {
                        var u = new MyUser(user,
                            SetAccountUniqueName(AccountById[accountId].Name,
                                AccountById[accountId].Id));
                        return u;
                    }
                }
                catch (Exception ex)
                {
                    _logger.Error(ex, $"Failed to get account {accountId} users list.");
                    return Enumerable.Empty<MyUser>();
                }
            });
    }

    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);
    }

但我收到此错误:

方法“Enumerable.SelectMany(IEnumerable, Func)”的类型参数无法从用法中推断出来。尝试显式指定类型参数。

c# linq async-await ienumerable yield
1个回答
0
投票

您不应该使用 LINQ 进行异步操作。 SelectMany 异步调用返回

Task
如果您不等待它们,这是错误的方式。

简单的

foreach
适用于您的情况,不要让事情复杂化。

public async Task<List<MyUser>> GetUsersAsync()
{
    var result = new List<MyUser>();
    foreach (var accountId in AccountById.Keys)
    {
        try
        {
            await foreach (var user in GetUsersForAsync(accountId))
            {
                var u = new MyUser(user,
                    SetAccountUniqueName(AccountById[accountId].Name,
                        AccountById[accountId].Id));
                result.Add(u);
            }
        }
        catch (Exception ex)
        {
            _logger.Error(ex, $"Failed to get account {accountId} users list.");
        }    
    }

    return result;
}
© www.soinside.com 2019 - 2024. All rights reserved.