2016-08-16 47 views
0

我的问题是类似Parallel Foreach Race Condition并行的foreach计数

了很多,但它并没有回答非常明确,它在这个意义上,我需要计算该物体在不同的换每个满足一定的条件。如果它确实需要将它添加到列表中。

所以像这样

List<int> MetCriteria = new List<int>(); 
Parallel.ForEach(dt.AsEnumerable(), (entry,state) => { 

    if (Convert.ToInt32(entry["Time"]) > 100)//in miliseconds 
    MetCriteria.add(Convert.ToInt32(entry["EntryID"]); 
}); 

所以,很显然这个名单不包含像线程锁或东西,一个正常的,每个会,因为我需要一些方法来保持MetCriteria对象同步的所有值,但我不确定如何做到这一点

任何帮助,请

+0

“if”语句是字面意思,你正在尝试做什么?如果是这样,你为什么使用并行处理? – Enigmativity

+0

我必须根据金额做不同的事情,所以如果它超过100,它会符合条件,如果没有,则需要检查其他变量,并将其添加到单独的列表中。那么我必须针对每个条目调用Web服务,根据输入时间可能需要一些时间 – Neil

+0

您是否简单地比较了像Convert.ToInt32(entry [“Time”])> 100'这样的值并添加了项目列表,然后调用Web服务?还是你在'if'里面调用一个web服务? – Enigmativity

回答

1

可以使用线程安全的集合像ConcurrentBag

var MetCriteria = new ConcurrentBag<int>(); 
Parallel.ForEach(dt.AsEnumerable(), (entry,state) => { 

    if (Convert.ToInt32(entry["Time"]) > 100)//in miliseconds 
    MetCriteria.add(Convert.ToInt32(entry["EntryID"]); 
}); 
1

确定您可以锁定您的列表以使其威胁安全。但我会使用像Dovydas Sopa建议的线程安全集合。

List<int> MetCriteria = new List<int>(); 
Parallel.ForEach(dt.AsEnumerable(), (entry, state) => 
{ 
    if (Convert.ToInt32(entry["Time"]) > 100)//in miliseconds 
    { 
     lock (MetCriteria) 
     { 
      MetCriteria.Add(Convert.ToInt32(entry["EntryID"])); 
     } 

    } 
}); 
+0

哪一个会更资源友好。这个答案或Dovydas Sopa的 – Neil

+0

如果我要使用你的答案,并且我有一个if语句在这个锁的外面,比如'if(MetCriteria.count> 1000)'它不应该影响它的正确性(它只是读取数据,不会改变) ? – Neil

+2

接受Dovydas Sopa的回答,这是应该如何完成的。锁只是防止来自不同线程的同时访问,并使_thread safe_。从技术上讲,对象被锁定,另一个访问线程必须等到上一个动作完成 – fubo