我想在Parallel.ForEach
上使用List<T>
的强大功能来验证例程。迭代List以确保属性不是&lt; 1.创建bool,如果验证发现验证方法调用中返回的错误,则设置为false。我被告知这段代码有问题,因为bool是原始的而不是线程安全的。有没有办法可以在具有大量内核和RAM的服务器上利用Parallel.ForEach
的强大功能,并确保在线程安全方面正常工作?
public static bool IsValid(List<Airport> entities)
{
bool isValid = true;
Parallel.ForEach<Airport>(entities, entity =>
{
// userId can't be less than 1
if (entity.userId < 1)
{
SiAuto.Main.LogMessage("Airport {0}: invalid userId {1}", entity.airportId, entity.userId);
isValid = false;
System.Diagnostics.Debugger.Break();
}
});
return isValid;
}
答案 0 :(得分:3)
你可以用PLINQ做到这一点:
public static bool IsValid(List<Airport> entities)
{
return !entities.AsParallel().Any(entity => entity.UserId < 1);
}
但是,由于并行运行的部分非常小,所以你没有任何改进,所以你应该坚持常规foreach
(或LINQ):
public static bool IsValid(List<Airport> entities)
{
return !entities.Any(entity => entity.UserId < 1);
}
答案 1 :(得分:1)
如果列表足够大,我会使用Enumerable.All
或return !entities.AsParallel().Any(x => x.UserId < 1);
来使用PLINQ方法:
return entities.AsParallel().All(x => !(x.UserId < 1));
或者
Parallel
通常在使用管道样式执行时,我发现PLINQ比display: inline-block;
类更合适,因为它消除了更新并行循环内共享资源的需要。
请注意,您应该对代码进行基准测试,以确保并行性是值得的。在许多情况下,如果列表不够大,这可能会降低性能。