以下是我在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);
}
});
答案 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())