使用Parallel.ForEach<;T>;设置Parallel.ForEach外部的bool

本文关键字:ForEach Parallel 外部 bool 设置 gt lt 使用 | 更新日期: 2023-09-27 18:01:00

我想在List<T>上使用Parallel.ForEach的幂作为验证例程。对List进行迭代以确保属性不是<1.如果验证在验证方法调用中发现返回的错误,则会创建一个设置为false的bool。有人告诉我,这个代码是有问题的,因为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;
}

使用Parallel.ForEach<;T>;设置Parallel.ForEach外部的bool

您可以使用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);
}

如果列表足够大,我会使用Enumerable.AnyEnumerable.All:的PLINQ方法

return !entities.AsParallel().Any(x => x.UserId < 1);

return entities.AsParallel().All(x => !(x.UserId < 1));

通常,当使用管道式执行时,我发现PLINQ比Parallel类更合适,因为它消除了更新并行循环中共享资源的需要。

请注意,您应该对代码进行基准测试,以确保并行性是值得的。在许多情况下,如果列表不够大,这可能会降低性能。