Enumerable.SelectMany 抛出错误 CS0411 - 无法从用法推断[重复]

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

我正在使用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 yield
2个回答
-1
投票

除非我遗漏了什么,否则你只需要更改你的签名即可

 public IEnumerable<User> getUsersFor(string accountId)

 public async Task<IEnumerable<User>> getUsersFor(string accountId)

并在异步方法中删除对

.Result
的调用并等待它们:

usersResponse = await myClient
    .ListUsersAsync(new ListUsersRequest { Marker = marker, MaxItems = MAX_ITEMS });

-1
投票

您需要删除

.Result
并将方法更改为与
async
await
关键字异步。

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

public async IEnumerable<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);
}
© www.soinside.com 2019 - 2024. All rights reserved.