Parallel.Foreach在c#中比正常foreach花费更多时间

时间:2015-02-16 11:15:34

标签: c#

以下是我在Parrllel.Foreach中使用的代码。但它与正常的foreach相同。这里filingDataItems,nonPeriodic,periodiccells是数据表。这是否因数据表而发生?

System.Threading.Tasks.Parallel.ForEach(tempfilingReferences, T2 =>
            {                             
                    Filing f = new Filing(
                                         T2.Id,
                                         T2.DocumentPeriod,
                                         T2.FilingDate,
                                         T2.VersionId,
                                         T2.DocumentId,
                                         T2.PrimaryPeriodTypeId,
                                         T2.IssuedAsPreliminaryFlag,
                                         T2.IssuedAsAmendmentFlag,
                                         T2.FilingDetails,
                                         T2.CompanyId,
                                 GetFilingDataItems(filingDataItems, T2.Id, nonPeriodic, periodiccells, filingToPeriodList, DPTPList, posList),
                                 GetPeriods(filingToPeriodList, periodInfoList, T2.Id),
                                 GetFilingToPeriods(filingToPeriodList, T2.Id),
                                         true,
                                         false,
                                         AuditedDataType.Financials,
                                         T2.FilingTypeList
                               );


                        lock (filingListnew)
                        {
                                filingListnew.Add(f);
                        }
            });

2 个答案:

答案 0 :(得分:2)

您正在锁定并行部分。 所以你在每个线程中等待活动线程移除锁。 所以这几乎与顺序的foreach相同。

例如:

<强> Parallel.Foreach:

循环1

Thread1:filingListnew.Add(Object1);

线程2:已锁定

Thread3:已锁定

Thread4:已锁定

循环2

Thread1:已锁定

Thread2:filingListnew.Add(Object2);

Thread3:已锁定

Thread4:已锁定

Cycle3 ...

<强>&#34;正常&#34;的foreach:

循环1

主线程:filingListnew.Add(Object1);

循环2

主线程:filingListnew.Add(Object2);

Cycle3 ...

正如您在示例中所看到的,您无法像使用ParallelForeach一样获得性能。

答案 1 :(得分:2)

你不是锁定每一步,而是尝试使用 LINQ

  filingListnew.AddRange(tempfilingReference
    .AsParallel()
    .Select(T2 => new Filing(...)));

如果您有保留订单

  filingListnew.AddRange(tempfilingReference
    .AsParallel()
    .AsOrdered()
    .Select(T2 => new Filing(...)));

你可能会发现有用的来创建列表,而不是添加它:

  filingListnew = tempfilingReference
    .AsParallel()
    .AsOrdered()
    .Select(T2 => new Filing(...)))
    .ToList();

Linq很容易在顺序/并行之间切换只注释 AsParallel()(或者把 AsSequential()