使用Parallel.ForEach <t>在Parallel.ForEach

时间:2015-07-04 18:45:38

标签: c# .net multithreading parallel-processing task-parallel-library

我想在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;
}

2 个答案:

答案 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.Allreturn !entities.AsParallel().Any(x => x.UserId < 1); 来使用PLINQ方法:

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

或者

Parallel

通常在使用管道样式执行时,我发现PLINQ比display: inline-block;类更合适,因为它消除了更新并行循环内共享资源的需要。

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