使用 Parallel.For 添加列表的线程 [英] Threading with Parallel.For Adding Lists

查看:42
本文介绍了使用 Parallel.For 添加列表的线程的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在使用 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 添加列表的线程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆