C# 跨嵌套的并行循环同步
我有一个类,其方法运行嵌套的C# 跨嵌套的并行循环同步,c#,.net-4.0,parallel-processing,C#,.net 4.0,Parallel Processing,我有一个类,其方法运行嵌套的ParallelFor循环。基本上,我迭代对象列表,然后是包含在每个对象属性中的列表 根据为内部循环中的每个对象计算的条件,我想添加到队列中。我使用“syncRoot”对象试图在添加到队列时保持并发性 public class ParallelTest { private static object syncRoot = new object(); public void Test() { List<MyLog> queue
ParallelFor
循环。基本上,我迭代对象列表,然后是包含在每个对象属性中的列表
根据为内部循环中的每个对象计算的条件,我想添加到队列中。我使用“syncRoot”对象试图在添加到队列时保持并发性
public class ParallelTest
{
private static object syncRoot = new object();
public void Test() {
List<MyLog> queue = new List<MyLog>();
...
Parallel.For(0, set.Count(), delegate(int i)
{
var obj = set[i];
List<Connection> conns = obj.GetConnections();
...
Parallel.For(0, conns.Count(), delegate(int j)
{
Connection c = conns[j];
MyLog log = new MyLog();
...
if (condition)
{
lock (syncRoot)
{
queue.Add(log);
}
}
}
}
Debug.WriteLine(queue.Count);
}
}
公共类并行测试
{
私有静态对象syncRoot=新对象();
公开无效测试(){
列表队列=新列表();
...
Parallel.For(0,set.Count(),委托(inti)
{
var obj=集合[i];
List conns=obj.GetConnections();
...
Parallel.For(0,conns.Count(),委托(intj)
{
连接c=接头[j];
MyLog log=new MyLog();
...
如果(条件)
{
锁定(同步根)
{
添加(日志);
}
}
}
}
Debug.WriteLine(queue.Count);
}
}
我的问题是,似乎并不是所有的对象都被添加到队列中。我正在测试一组200个对象,并将条件
替换为真
,因此我预计队列.计数
为200。然而,我得到了奇怪的结果…有时是200,有时是198或199
我在这里做错了什么?我如何确保每个线程都得到解释?您可以使用
ConcurrentQueue类
代替列表
。请参阅
更多信息。这似乎是Linq的一个优秀候选人 假设由
…
表示的代码可以封装在带有签名的方法中:
void Initialize(MyLog log, Connection conn, SomeUnknownType obj)
您的代码可以简化为以下linq语句:
var logs = set
.AsParallel()
.SelectMany(
obj =>
obj.GetConnections()
.Select(conn => new{obj, conn}))
.Select(x => {
var o = new{x.obj, x.conn, log = new MyLog()};
Initialize(o.log, o.conn, o.obj); //or just do work inline
return o;
})
.Where(x => x.obj... && x.conn...) //someCondition
queue = logs.ToList();
视为
set.Count()
相对较高,在集合上进行并行化将确保工作在可用内核上得到合理的分配。以后无需再次并行化。这是一个相当广泛的局部变量锁定策略。如果您只需要在队列
的相同范围内声明syncLock
使用它。更好的是,既然不能保证排序,为什么不使用ConcurrentBag
并完全取消锁定?尝试了ConcurrentBag
。同样的行为。第一次测试200,第二次199。我可能会失去理智,但我收回了我以前的评论。这似乎正在起作用。我将在下一次测试中测试它地面,看看我是否可以打破它,但这可能是我需要的解决方案。如果你可以远离显式循环和显式锁定,你肯定不会太容易受到这种问题的影响。在创建每个日志后,“…”的一部分是一些处理,需要一个变量(并且可能很长)时间量,所以并行性很重要。未知。我正在使用200-300进行批量测试,认为这将是一个很高的量。但这取决于时间。@Paul希望对我的答案所做的更改符合您的需要。他们将确保额外的工作并行化。