问题描述
我在使用 Parallel.For 方法时遇到问题.我正在拨打 GET 电话以取回列表.然后我想将该列表添加到主列表中.我尝试过非线程安全的 addRange,并且会在列表中返回错误的数据.我也试过使用 ConcurrentBag 也没有得到正确的数据.当我说没有获得正确的数据时,我的意思是列表中的某些数据要么重复,要么被覆盖.
I am having trouble using the Parallel.For method. I am making a GET call to get back a list. Then I want to take that list and add it to the main list. I have tried addRange which is not thread safe, and will return the wrong data in the list. I have also tried to use ConcurrentBag which also does not get the right data. When I say does not get the right data I mean some of the data in the lists is either repeating or gets over written.
这是我的代码(更新):
Here is my code(updated):
var thisLock = new Object();
var list = new List<Person>();
Parallel.For(1, 10, x =>
{
request.Page = x;
response = Get(request); // call to client
lock(thisLock)
{
list.AddRange(response);
}
}
除了 addRange 或 ConcurrentBag 之外的任何其他想法
Any other ideas besides addRange or ConcurrentBag
推荐答案
我在这里做了一些假设,但看起来你的问题是你的 request
/response
变量不在 Parallel.For
调用范围内.
I am making a few assumptions here, but it would appear that your problem is the fact that your request
/response
variables are not scoped within the Parallel.For
call.
问题是你进行了一个(大概)同步的 Get
调用,它更新了 response
变量,但假设你有 X 个线程都使用相同的响应,如果得到在任何给定点更新,即当另一个线程将其添加到列表中时,这将很可能导致重复数据.
The problem is you make a (presumably) synchronous Get
call which updates the response
variable but given you have X threads all working with that very same response if that gets updated at any given point i.e. whilst another thread is adding it to the list, then that is going to very well lead to duplicate data.
同样适用于 request
,你有一个明显的竞争条件,这意味着当一个线程改变 request.Page
而另一个线程只是 即将拉取数据,那么您就有效地跨多个线程拉取同一页面.
Same goes for the request
, you have an obvious race condition meaning that when one thread changes the request.Page
and another thread is just about to pull the data then you are effectively pulling the same page across various threads.
解决方案很简单,在本地创建您的request
/response
对象
The solution is simple, create your request
/response
objects locally
var list = new ConcurrentBag<T>();
Parallel.For(1, 10, x =>
{
var request = // create new request;
request.Page = x;
var response = Get(request); // call to client
foreach (var item in response) {
list.Add(item); // add it main list
}
}
这篇关于使用 Parallel.For 添加列表的线程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!