我有两个嵌套的foreach
循环,需要运行大量的数据和计算。常规foreach
循环耗时太长(几个小时)。
所以,我找到了加快速度的方法并找到Parallel.ForEach
。这是我第一次处理并行化,但examples似乎很容易。
以下是我的代码,这个问题是局部变量(我认为,至少)。为在并行循环之外工作正常的节点添加错误。
Parallel.ForEach(allNodes, (startNode) =>
{
Parallel.ForEach(allNodes, (endNode) =>
{
if (startNode != endNode)
{
List<Geo_Model_Struct> route = pathfinder.getRouteOptimised(startNode, endNode);
if (route.Count <= 0)
{
//failed to find route
errors.Add(string.Format("Cound not find a route from {0} to {1}", startNode, endNode));
}
else
{
List<Geo_Model_Struct> accessibleRoute = accessiblePathfinder.getRouteOptimised(startNode, endNode);
if (accessibleRoute.Count <= 0)
{
//failed to find route
errors.Add(string.Format("Cound not find an accessible route from {0} to {1}", startNode, endNode));
}
}
}
endCount++;
System.Diagnostics.Debug.WriteLine("I: {0}/{1}\tJ: {2}/{3}", startCount, allNodes.Count - 1, endCount, allNodes.Count - 1);
}
);
startCount++;
});
我猜测它与route
局部变量有关,因为几乎所有已检查的路线都失败了。但是我不知道如何可靠地调试这种东西,所以任何帮助都会受到赞赏。
修改
我正在测试所有可能的路线,以确保它们都能正常工作。对于大多数测试,route.Count
应为> 0
。使用传统的foreach
循环时就是这种情况(例如500次中的15次route.Count <= 0
是true
)
在大多数情况下使用Parallel.ForEach
route.Count
0
时(例如,在500次中的494区域内),实际上很少有人通过测试并且在查看时大多数错误并行失败,使用传统的foreach
解决
我找到了一种方法来消除在getRouteOptimised
方法中从数据库中获取数据的需要。这解决了这个问题。仍然不确定导致问题的db连接到底是什么,但现在可以正常工作。
答案 0 :(得分:1)
在没有看到其余代码的情况下,我怀疑问题在于pathfinder和accessiblepathfinder对象。它们可能不是线程安全的。 可能绕过这种方法的方法是在内部foreach循环中本地创建这些变量。
if (startNode != endNode)
{
// Create and Initialise pathfinder here
MyPathFinderObject pathfinder = new MyPathFinderObject(<parameters>);
List<Geo_Model_Struct> route = pathfinder.getRouteOptimised(startNode, endNode);
if (route.Count <= 0)
.../...
else
{
// Create and Initialise accessiblePathfinder here
MyAccessiblePathFinderObject accessiblePathfinder = new MyAccessiblePathFinderObject(<parameters>);
List<Geo_Model_Struct> accessibleRoute = accessiblePathfinder.getRouteOptimised(startNode, endNode);
.../...
}
}
然而,无法保证这会奏效。
从属性和方法获取数据时,您必须非常谨慎。众所周知,大型物体模型以令人难以置信的迂回方式共享可变状态。