繁体   English   中英

Parallel.Foreach比C#中的正常foreach花费更多的时间

[英]Parallel.Foreach taking more time than normal foreach in c#

下面是我在Parrllel.Foreach中使用的代码。 但这与普通的foreach花费的时间相同。 在此,filingDataItems,非Periodic,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);
                        }
            });

您正在锁定并行部分。 因此,您在每个线程中等待活动线程删除锁。 因此,这与顺序foreach几乎相同。

例如:

Parallel.Foreach:

循环1

线程1:archiveListNew.Add(Object1);

线程2:锁定

线程3:锁定

线程4:锁定

循环2

线程1:锁定

线程2:archiveListNew.Add(Object2);

线程3:锁定

线程4:锁定

周期3 ...

“普通” foreach:

循环1

主线程:archiveListnew.Add(Object1);

循环2

主线程:archiveListnew.Add(Object2);

周期3 ...

从示例中可以看到,您无法像使用ParallelForeach一样获得性能。

您宁可不要在每一步都锁定 ,而是尝试使用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()

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM