这些列表是否是Parallel.For中的安全线程?

时间:2015-10-16 12:54:01

标签: c# multithreading parallel-processing thread-safety parallel.foreach

我必须从Parallel.ForEach删除 lock 对象。我应该使用ConcurrentBag还是删除它?没有 lock 对象,它是否是线程安全的?

resultsList<>

Parallel.ForEach(entityList, options,
() =>
{
    List<Customer> childrenResult = new List<Customer>();
    return childrenResult;
},
(childrenObject, loopState, childrenResult) =>
{
    childrenResult.AddRange(currentChildrenManager.Prepare(childrenObject, currentAnalyticalDataHolder, () => loopState.IsStopped, out childrenAllData));
    return childrenResult;
},
(childrenResult) =>
{
    lock (lockingObject)
    {
        if (childrenResult == null)
            results.AddRange(new List<Customer>());
        else if (currentChildrenManager.RowOrFilteredRowLimitation == null)
            results.AddRange(childrenResult);
        else
        {
            int leftCount = currentChildrenManager.RowOrFilteredRowLimitation.GetRelativRowLimitation(provider.IsForGenerationTime) - results.Count();
            if (leftCount > 0)
            {
                if (childrenResult.Count() > leftCount)
                {
                    tAllData = currentChildrenManager.OnlyFirst;
                    results.AddRange(childrenResult.Take(leftCount));
                }
                else
                    results.AddRange(childrenResult);
            }
            else
            {
                tAllData = currentChildrenManager.OnlyFirst;
            }
        }
    }
});

1 个答案:

答案 0 :(得分:1)

我假设您提供的代码使用了一个带有protected值的重载,并分别使用localInit localFinallyFunc<T>看起来像这样:

Action<T>

仍然是强制性的,因为最终操作必须并行地将项目添加到基础列表。您可以使用public static ParallelLoopResult ForEach<TSource, TLocal>( IEnumerable<TSource> source, ParallelOptions parallelOptions, Func<TLocal> localInit, Func<TSource, ParallelLoopState, TLocal, TLocal> body, Action<TLocal> localFinally ) 进行最后的连接,但我建议您使用这两种方法进行基准测试,以确定哪种方式可以获得更高效的结果。

或许可能更适合您的不同方法是使用PLINQ。这样,您可以并行处理多个项目,最后只使用ConcurrentBag<T>创建包含结果的ToList

List<T>