提问人:Amir M 提问时间:11/9/2023 最后编辑:Amir M 更新时间:11/9/2023 访问量:62
Enumerable.SelectMany 引发错误 CS0411 - 无法从使用情况推断
Enumerable.SelectMany throws Error CS0411 - cannot be inferred from the usage
问:
我正在使用 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(accountId))
{
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(accountId))
{
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<TSource, TResult>(IEnumerable, Func<TSource, IEnumerable>)”的类型参数。尝试显式指定类型参数。
答:
0赞
Svyatoslav Danyliv
11/9/2023
#1
不应将 LINQ 用于异步操作。选择许多异步调用返回,如果您不等待它们,则这是错误的方式。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;
}
评论
.SelectMany<User>(...
AccountById
AccountById
ConcurrentDictionary<string, Account>
MyUser
IEnumerable<MyUser>