【发布时间】:2023-01-26 18:53:07
【问题描述】:
当我使用 foreach 循环或带锁的 Parallel.ForEach 时,数据正常输出,但是当我使用没有 lock 的 Parallel.ForEach 时,数据不一致并发生数据丢失。此外,如果我使用每个模型项作为 Parallel.ForEach 中的参数并删除模型,而不是模型 ApiFileItems,则输出是一致的并且没有数据丢失。
现在lock 我面临的问题是性能非常慢。
但是当我在没有锁的情况下使用Parallel.ForEach循环时,性能很快但是数据不一致并且发生数据丢失。现在我坚持了将近 4 天,没有得到任何提高性能的解决方案。
private static void ParallelExecution(JArray ContentNode,
ApiFileItems apiFileItems, ApiTypeItem apiTypeItem)
{
Parallel.Foreach(ContentNode.Values(), new ParallelOptions(){}, (rootNode) =>
{
lock (ContentNode)
{
if (rootNode.HasValues)
{
ParallelRootItemExecution(rootNode, apiFileItems, apiTypeItem);
}
else
{
//Log the message
}
}
});
}
private static void ParallelRootItemExecution(JToken rootNode,
ApiFileItems apiFileItems, ApiItemType apiItemType)
{
Parallel.ForEach<JToken>(rootNode.Values(),
new ParallelOptions() {MaxDegreeOfParallelism = 4}, (metaNode) =>
{
lock (rootNode)
{
bool foundValue = false;
apiFileItems.relativeFilePath = metaNode["valueString"].ToString();
if (!foundFolderItems.TryGetValue(apiFileItems.relativeFilePath,
out foundValue))
{
foundFolderItems.TryAdd(apiFileItems.relativeFilePath, true);
ParallelExecution((String.FormatapiFileItems.relativeGroupUrl,
apiFileItems.hostName, apiFileItems.publicationId,
apiFileItems.relativeFilePath), apiFileItems,apiItemType);
}
}
});
}
不使用lock时会出现数据丢失,数据不一致。
【问题讨论】:
-
那么,你同步/锁定全部的并行工作项,实际上强制每个工作项一个接一个地按顺序运行。与完全不使用 Parallel.Foreach 时一样。您需要确定工作项中可能同时访问相同资源/变量/属性/字段/集合/等的代码部分,并且仅同步/锁定这些部分,而不是整个工作项.如果几乎整个工作项目是
-
如果没有锁,数据会以何种方式混乱(您期望什么,您得到了什么 - 堪称典范)?
foundFolderItems是什么类型?此外,嵌套Parallel.For*(大部分)从来都不是一个好主意。
标签: c# multithreading performance parallel-processing parallel.foreach