3 回答

TA貢獻1820條經驗 獲得超9個贊
對于這樣的問題,使用 LINQ 很方便。LINQ 生成不可變的結果,因此您可以避免并發問題,也不需要任何專用集合。
一般來說,使用LINQ或類似的編程技術(即像函數式程序員一樣思考)將使多線程更容易。
public async Task<IEnumerable<Route>> GetRoutes(IEnumerable<Coordinates> origins, IEnumerable<Coordinates> destinations)
{
var tasks = origins
.SelectMany
(
o => destinations.Select
(
d => _routeService.GetRoute(o, d)
)
);
await Task.WhenAll( tasks.ToArray() );
return tasks.SelectMany( task => task.Result );
}

TA貢獻1806條經驗 獲得超5個贊
正如評論中指出的那樣,我建議您可以使用 來確定要完成的所有任務并獲得結果。為此,您可以更新代碼,如下所示。Task.WhenAll()return await Task.WhenAll(tasks);
public async Task<IEnumerable<Route>> GetRoutes(IEnumerable<Coordinates> origns, IEnumerable<Coordinates> destinations)
{
ConcurrentBag<Route> routes = new ConcurrentBag<Route>();
List<Task> tasks = new List<Task>();
foreach (var origin in origns)
{
foreach (var destination in destinations)
{
tasks.Add(_routeService.GetRoute(origin, destination));
}
}
var response = await Task.WhenAll(tasks);
foreach (var item in response)
{
routes.Add(item);
}
return routes;
}
}
由于所有調用都將返回相同的類型,因此無需在其他循環中啟動第二個調用。此外,通過這種方式,您將避免鎖定線程執行,并且您的程序將運行得更加同步。要查看 與 之間的區別,您可以查看此內容。foreachTask.WaitAll()WhenAll()WaitAll()

TA貢獻2016條經驗 獲得超9個贊
您可以使用延續,而不是使用該方法直接創建任務。Task.Run
foreach (var origin in origns)
{
foreach (var destination in destinations)
{
tasks.Add(
_routeService.GetRoute(origin, destination)
.ContinueWith(response =>
{
foreach (var item in response.Result)
routes.Add(item);
})
);
}
}
因此,該方法將異步執行,而無需創建單獨的線程。從中獲得的結果將在單獨的線程(任務)中處理。GetRoute
但是,僅當結果需要很長時間才能處理時,才需要這樣做。否則,根本不需要單獨的線程。
- 3 回答
- 0 關注
- 202 瀏覽
添加回答
舉報