如何在控制器进行并行调用时等待结果
How to wait for the result while controller is making parallel call
我正在尝试从数据库 (GetAccountDetailAsync) 中查找一组帐户的帐户详细信息,并希望并行 运行 以使其更快。
[HttpPost]
public async Task<IHttpActionResult> GetAccountsAsync(IEnumerable<int> accountIds)
{
var resultAccounts = new List<AccountDetail>();
var task = Task.Run(() =>
{
Parallel.ForEach(accountIds, new ParallelOptions
{
MaxDegreeOfParallelism = 5
}, async accountId =>
{
var response = await GetAccountDetailAsync(accountId).ConfigureAwait(false);
resultAccounts.AddRange(response);
});
});
task.Wait();
return Ok(resultAccounts);
}
但我得到的不是结果,而是 task.Wait。
不确定为什么 task.Wait 没有被阻止。
"An asynchronous module or handler completed while an asynchronous operation was still pending."
Parallel.ForEach
不适用于 async
操作,但您可以启动所有任务,然后使用 Task.WhenAll
:
等待它们全部完成
[HttpPost]
public async Task<IHttpActionResult> GetAccountsAsync(IEnumerable<int> accountIds)
{
Task<List<AccountDetail>>[] tasks = accountIds.Select(accountId => GetAccountDetailAsync(accountId)).ToArray();
List<AccountDetail>[] results = await Task.WhenAll(tasks);
return Ok(results.SelectMany(x => x).ToList());
}
假设您拥有或可以轻松获得没有异步部分的方法 GetAccountDetail
,这将是最简单的方法:
[HttpPost]
public async Task<IHttpActionResult> GetAccountsAsync(IEnumerable<int> accountIds)
{
var resultList = accountIds.AsParallel()
.WithDegreeOfParallelism(5)
.Select(GetAccountDetail)
.ToList();
return Ok(resultList);
}
我正在尝试从数据库 (GetAccountDetailAsync) 中查找一组帐户的帐户详细信息,并希望并行 运行 以使其更快。
[HttpPost]
public async Task<IHttpActionResult> GetAccountsAsync(IEnumerable<int> accountIds)
{
var resultAccounts = new List<AccountDetail>();
var task = Task.Run(() =>
{
Parallel.ForEach(accountIds, new ParallelOptions
{
MaxDegreeOfParallelism = 5
}, async accountId =>
{
var response = await GetAccountDetailAsync(accountId).ConfigureAwait(false);
resultAccounts.AddRange(response);
});
});
task.Wait();
return Ok(resultAccounts);
}
但我得到的不是结果,而是 task.Wait。 不确定为什么 task.Wait 没有被阻止。
"An asynchronous module or handler completed while an asynchronous operation was still pending."
Parallel.ForEach
不适用于 async
操作,但您可以启动所有任务,然后使用 Task.WhenAll
:
[HttpPost]
public async Task<IHttpActionResult> GetAccountsAsync(IEnumerable<int> accountIds)
{
Task<List<AccountDetail>>[] tasks = accountIds.Select(accountId => GetAccountDetailAsync(accountId)).ToArray();
List<AccountDetail>[] results = await Task.WhenAll(tasks);
return Ok(results.SelectMany(x => x).ToList());
}
假设您拥有或可以轻松获得没有异步部分的方法 GetAccountDetail
,这将是最简单的方法:
[HttpPost]
public async Task<IHttpActionResult> GetAccountsAsync(IEnumerable<int> accountIds)
{
var resultList = accountIds.AsParallel()
.WithDegreeOfParallelism(5)
.Select(GetAccountDetail)
.ToList();
return Ok(resultList);
}