我已經切換到.net Core的某些項目,並且現在遇到了Parallel.ForEach的問題。在過去,我經常擁有一個id值列表,然後我將使用它來發出Web請求以獲取完整數據。這將是這個樣子:.net Core Parallel.ForEach問題
Parallel.ForEach(myList, l =>
{
// make web request using l.id
// process the data somehow
});
那麼,在.NET核心的Web請求都必須標記await
這意味着Parallel.ForEach行動必須標記async
。但是,將Parallel.ForEach標記爲async
意味着我們有一個導致問題的方法void async
。在我的特殊情況下,這意味着響應返回之前的並行循環中的所有Web請求都已完成,這既困難又會導致錯誤。
問:在這裏使用Parallel.ForEach有什麼替代方法?
一個可能的解決方案,我發現是包裝一個任務內的並行循環,等待任務:
await Task.Run(() => Parallel.ForEach(myList, l =>
{
// stuff here
}));
(這裏找到:Parallel.ForEach vs Task.Run and Task.WhenAll)
但是,這不是爲我工作。當我使用它時,我仍然最終在循環完成之前返回到應用程序。
另一種選擇:
var tasks = new List<Task>();
foreach (var l in myList)
{
tasks.Add(Task.Run(async() =>
{
// stuff here
}));
}
await Task.WhenAll(tasks);
這似乎是工作,但是是唯一的選擇?看起來新的.net Core已經讓Parallel.ForEach變得虛擬無用(至少在嵌套網絡調用時)。
任何協助/建議表示讚賞。
'async/await'設計用於長時間和阻塞** I/O操作**,而'Parallel'則用於長時間阻塞** CPU操作**。如果你發現自己試圖在一個'Parallel'函數體內編寫異步代碼,那麼你做錯了什麼。考慮使用[Task.WhenAll](https://msdn.microsoft.com/en-us/library/system.threading.tasks.task.whenall(v = vs.110).aspx)。 –
除了上面的評論,當你做Task.Run(async()=> ...)時,你也幾乎總是做錯了什麼。 – Evk
你應該看看[TPL Dataflow](https://msdn.microsoft.com/en-us/library/hh228603(v = vs.110).aspx)。讓你的生活變得更輕鬆。它不是.NET Framework的一部分,但你可以使用nuget來獲取它, – ThePerplexedOne