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 關注
- 164 瀏覽
添加回答
舉報