我正在使用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 )”的类型参数无法从用法中推断出来。尝试显式指定类型参数。
您不应该使用 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;
}