Parallel.ForEach 中的不一致 [关闭]
Posted
技术标签:
【中文标题】Parallel.ForEach 中的不一致 [关闭]【英文标题】:Inconsistency in Parallel.ForEach [closed] 【发布时间】:2017-01-16 10:19:10 【问题描述】:我正在使用 Parallel.foreach 进行超过 500 次迭代。
我的循环是这样的:
Parallel.ForEach(indexes, (index) =>
//parentCreation with index object
parent=create(index);
//call of function to create children
createChildrenOfType1(parent);
createChildrenOfType2(parent);
);
我面临不一致的输出。父母的创建是正确的,但孩子的创建是不一致的。 有时不创建子项,有时只创建少数子项,依此类推。 子创建方法再次具有 for 循环来创建 100 个子。
如何在使用并行 foreach 进行父创建时使我的子创建保持一致。
【问题讨论】:
我认为您将不得不展示您对这些创建方法的实现。 线程不安全的对象是线程不安全的 如果您曾经玩过 GTA 并且玩飞镖喝得太多 - 这就是在多线程环境中使用不安全对象时的世界感觉。这不正常。 【参考方案1】:我在这里看到的一个问题是您正在修改未在 Parallel.ForEach 代码块中声明的变量,在这种情况下您应该锁定它们。
Parallel.ForEach(indexes, (index) =>
//parentCreation with index object
lock (lockerObject)
parent=create(index);
//call of function to create children
createChildrenOfType1(parent);
createChildrenOfType2(parent);
);
通过使用锁,它可以确保线程正确同步。
【讨论】:
谢谢大家。是的,一些变量是在并行 for 循环之外初始化的,这就是不一致的原因。 我遇到了类似的问题,并且解决了它。不确定这是否是“最好的”方式,但它很容易并且有效。我投了赞成票!【参考方案2】:假设您的Parent
对象有一个List<Child> Children
并且您的createChildrenOfTypeX
函数正在向Parent.Children 列表添加一个新子级,并且那些createChildrenOfTypeX
也在运行一组并行代码,那么List 实现必须线程安全;标准 System.Collections.Generic 实现不是线程安全的。
此外,如果您有一个 Parent
的外部集合,您要向其中添加新实例化的父级,这也必须是线程安全的,否则您也可能会丢失您的父级实例。
【讨论】:
以上是关于Parallel.ForEach 中的不一致 [关闭]的主要内容,如果未能解决你的问题,请参考以下文章
Python 中的 C# Parallel.Foreach 等效项
如何正确调用 Parallel.ForEach 循环中的调用异步方法[重复]
Stringbuilder用于Parallel.Foreach循环