2 回答
TA贡献1815条经验 获得超13个赞
这里不需要 Tasks 和 Parrallel 循环。我假设你的_api调用是 IO 绑定的?你想要更像这样的东西:
var tasksA = new List<Task<ApiResponse<string>>>();
var tasksB = new List<Task<ApiResponse<string>>>();
//fire off all the async tasks
foreach(var it in iterations){
tasksA.Add(_Api.TaskA(orderResult.OrderId));
tasksB.Add(_Api.TaskB(orderResult.OrderId));
}
//await the results
await Task.WhenAll(tasksA).ConfigureAwait(false);
foreach (var task in tasksA)
{
//no need to get GetAwaiter(), you've awaited above.
task.Result;
}
//to get the most out of the async only await them just before you need them
await Task.WhenAll(tasksB).ConfigureAwait(false);
foreach (var task2 in tasksB)
{
task2.Result;
}
这将触发您所有的 api 调用,async然后在结果返回时阻塞。您 Parallel for 和 tasks 只是使用额外的线程池线程来实现零收益。
如果_api受 CPU 限制,您可以从中受益,Task.Run但我猜这些是 web api 或其他东西。所以Task.Run除了使用额外的线程之外什么都不做。
TA贡献1854条经验 获得超8个赞
正如其他人所建议的那样,删除Parallel, 和await在asserting他们之前完成的所有任务。
我还建议.Result从每个任务中删除,而await不是它们。
public async Task ConcurrencyIssueTest(int iterations)
{
var orderResult = await _driver.PlaceOrder();
var taskA = _Api.TaskA(orderResult.OrderId);
var taskB = _Api.TaskB(orderResult.OrderId);
await Task.WhenAll(taskA, taskB);
var taskAResult = await taskA;
taskAResult.ShouldNotBeNull();
taskAResult.StatusCode.ShouldBe(HttpStatusCode.OK);
var taskBResult = await taskB;
taskBResult.ShouldNotBeNull();
taskBResult.StatusCode.ShouldBe(HttpStatusCode.OK);
}
- 2 回答
- 0 关注
- 147 浏览
添加回答
举报