我已经切换到.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