问题描述
对于某些项目,我已经切换到.net Core,并且Parallel.ForEach遇到了问题.过去,我经常有一个id值列表,然后将其用于发出Web请求以获取完整数据.看起来像这样:
I've switched over to .net Core for some projects and am now having a problem with Parallel.ForEach. In the past I often had a List of id values which I then would use to make web requests in order to get the full data. It would look something like this:
Parallel.ForEach(myList, l =>
{
// make web request using l.id
// process the data somehow
});
好吧,在.net Core中,Web请求必须全部标记为await
,这意味着Parallel.ForEach操作必须标记为async
.但是,将Parallel.ForEach操作标记为async
意味着我们有一个导致问题的void async
方法.在我的特殊情况下,这意味着响应在并行循环中的所有Web请求都已完成之前返回到应用程序 ,这既麻烦又会导致错误.
Well, in .net Core the web requests must all be tagged await
which means the Parallel.ForEach action must be tagged with async
. But, tagging a Parallel.ForEach action as async
means we have a void async
method which causes issues. In my particular case that means the response returns to the application before all of the web requests in the Parallel loop are completed which is both awkward and causes errors.
问题:这里使用Parallel.ForEach的替代方法是什么?
Question: What are the alternatives to using Parallel.ForEach here?
我发现的一种可能的解决方案是将Parallel循环包装在Task中并等待任务:
One possible solution I found was to wrap the Parallel loop inside of a Task and await the task:
await Task.Run(() => Parallel.ForEach(myList, l =>
{
// stuff here
}));
(在此处找到: Parallel.ForEach与Task.Run and Task .WhenAll )
但是,这对我不起作用.当我使用它时,我仍然会在循环完成之前返回到应用程序.
But, that isn't working for me. When I use that I still end up returning to the application before the loop is completed.
另一个选择:
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毫无用处(至少在嵌套Web调用方面).
This appears to work, but is that the only option? It seems that the new .net Core has rendered Parallel.ForEach virtually useless (at least when it comes to nested web calls).
感谢您的协助/建议.
推荐答案
这三个方法都不是很好.
Neither of those 3 apporaches are good.
在这种情况下,您不应使用Parallel
类或Task.Run
.
You should not use the Parallel
class, or Task.Run
on this scenario.
相反,请使用async
处理程序方法:
Instead, have an async
handler method:
private async Task HandleResponse(Task<HttpResponseMessage> gettingResponse)
{
HttpResponseMessage response = await gettingResponse;
// Process the data
}
然后使用Task.WhenAll
:
Task[] requests = myList.Select(l => SendWebRequest(l.Id))
.Select(r => HandleResponse(r))
.ToArray();
await Task.WhenAll(requests);
这篇关于.net Core Parallel.ForEach问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!