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 中的不一致 [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

.Net 中的多个 Parallel.ForEach 循环

Python 中的 C# Parallel.Foreach 等效项

如何正确调用 Parallel.ForEach 循环中的调用异步方法[重复]

Stringbuilder用于Parallel.Foreach循环

Parallel.ForEach 中是不是有“继续”的等价物?

将 MVC 视图呈现为 Parallel.ForEach 中的字符串时的依赖注入问题