这里最简单的选择是切换到plinq:
Location findClosestLocation(Location myLocation, List<Location> allLocations)
{
return allLocations
.AsParallel()
.Min(location => greatCircle(myLocation, location));
}
也就是说,这基本上只是
aggregation with parallel constructs
. 如果你想坚持使用并行类,你有几个选择。一个选项是使用锁定在块中自己同步这个文件。我不建议这样做,因为这会影响你的整体表现。
更好的选择是使用
Parallel.ForEach
提供本地状态的方法。它们允许您将此重写为:
Location findClosestLocation(Location myLocation, List<Location> allLocations)
{
double closest = double.MaxValue;
Location closestLoc = null;
object sync = new object();
Parallel.ForEach<Location, Tuple<double,Location>(
allLocations,
() => new Tuple(double.MaxValue, null),
(location, loopState, localState) =>
{
double d = greatCircle(myLocation, aLoc);
if (d < localState.Item1)
return new Tuple(d, aLoc);
else
return localState;
},
localState =>
{
lock(sync)
{
if (localState.Item1 < closest)
{
closest = localState.Item1;
closestLoc = localState.Item2;
}
}
}
);
return closestLoc;
}
我覆盖使用
local state for aggregations in detail on my blog
. 这基本上将操作更改为每个线程一个锁操作,而不是每个处理元素一个锁,因此您比简单的锁解决方案获得更高的吞吐量。