并行。foreach循环不起作用。
我有两种可以为我完成工作的方法,一种是串行的,另一种是平行的。 并行化的原因是因为有很多迭代(大约100,000左右) 由于某种原因,平行的人会跳过或双重进行一些迭代,我不知道如何调试它。
串行方法
for(int i = somenum; i >= 0; i-- ){
foreach (var nue in nuelist)
{
foreach (var path in nue.pathlist)
{
foreach (var conn in nue.connlist)
{
Func(conn,path);
}
}
}
}
并行方法
for(int i = somenum; i >= 0; i-- ){
Parallel.ForEach(nuelist,nue =>
{
Parallel.ForEach(nue.pathlist,path=>
{
Parallel.ForEach(nue.connlist, conn=>
{
Func(conn,path);
});
});
});
}
在路径类中的
Nue firstnue;
public void Func(Conn conn,Path path)
{
List<Conn> list = new(){conn};
list.AddRange(path.list);
_ = new Path(list);
}
public Path(List<Conn>)
{
//other things
firstnue.pathlist.Add(this);
/*
firstnue is another nue that will be
in the next iteration of for loop
*/
}
它们都是相同的方法,当然,foreach
和Parallel.Foreach
循环。
该代码适用于在这里(github)(github)页)
I have 2 methods that can do the work for me, one is serial and the other one is parallel.
The reason for parallelization is because there are lots of iteration(about 100,000 or so)
For some reason, the parallel one do skip or double doing some iterations, and I don't have any clue how to debug it.
The serial method
for(int i = somenum; i >= 0; i-- ){
foreach (var nue in nuelist)
{
foreach (var path in nue.pathlist)
{
foreach (var conn in nue.connlist)
{
Func(conn,path);
}
}
}
}
The parallel method
for(int i = somenum; i >= 0; i-- ){
Parallel.ForEach(nuelist,nue =>
{
Parallel.ForEach(nue.pathlist,path=>
{
Parallel.ForEach(nue.connlist, conn=>
{
Func(conn,path);
});
});
});
}
Inside Path class
Nue firstnue;
public void Func(Conn conn,Path path)
{
List<Conn> list = new(){conn};
list.AddRange(path.list);
_ = new Path(list);
}
public Path(List<Conn>)
{
//other things
firstnue.pathlist.Add(this);
/*
firstnue is another nue that will be
in the next iteration of for loop
*/
}
They are both the same method except, of course, foreach
and Parallel.ForEach
loop.
the code is for the code in here (GitHub page)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
list&lt; t&gt;
,我认为您与firstNue.pathlist
一起使用,不是线程安全。这意味着,当您从相同的列表中添加/删除项目同时从多个线程中添加/lt; t&gt;
时,您的数据将损坏。为了避免这个问题,最简单的解决方案是使用锁定,因此多个线程不会一次尝试一次修改列表。但是,一个锁可以实质上序列列表操作,如果您在
func
中唯一要做的就是更改列表,则您可能不会通过并行化代码来获得太多收益。但是,如果您仍然想尝试一下,您只需要更改以下内容:对此:
List<T>
, which I assume you use withfirstnue.pathlist
, isn't thread-safe. That means, when you add/remove items from the sameList<T>
from multiple threads at the same time, your data will get corrupt. In order to avoid that problem, the simplest solution is to use a lock, so multiple threads doesn't try to modify list at once.However, a lock essentially serializes the list operations, and if the only thing you do in
Func
is to change a list, you may not gain much by parallelizing the code. But, if you still want to give it a try, you just need to change this:to this:
感谢 sedat-kapanoglu ,我发现问题确实与线程安全有关。解决方案是将每个
列表&lt; t&gt;
更改为concurrentbag&lt; t&gt;
。对于像我一样的每个人,“平行不使用收藏”的解决方案是从
system.collections.generic
更改为system.collections.collections.concurrent
Thanks to sedat-kapanoglu, I found the problem is really about thread safety. The solution was to change every
List<T>
toConcurrentBag<T>
.For everyone, like me, The solution of "parallel not working with collections" is to change from
System.Collections.Generic
toSystem.Collections.Concurrent