-2

私はParallel.foreachを500回以上の反復で使用しています。私は一貫性のない出力を直面していますParallel.ForEachの不一致

Parallel.ForEach(indexes, (index) => 
{ 

//parentCreation with index object 
parent=create(index); 

//call of function to create children 
createChildrenOfType1(parent); 
createChildrenOfType2(parent); 
}); 

私のループのようなものです。親は正しく作成されますが、子の作成には一貫性がありません。 子が作成されないことがあります。作成される子もほとんどありません。 子作成メソッドには、forループで100個の子を作成する必要があります。

パラレルforeachを親作成に使用しているときに、どのようにして子の作成を一貫させることができますか。 ;あなたParentオブジェクトはList<Child> Childrenを持っており、あなたのcreateChildrenOfTypeX機能がParent.Childrenリストに新しい子を追加すると、それらのcreateChildrenOfTypeXも、リストの実装がスレッドセーフでなければならないコードの並列セットを実行していると仮定すると、

+3

あなたはそれらの作成メソッドの実装を示す必要があると思います。 –

+4

スレッドが安全でないオブジェクトはスレッドが安全ではない – milleniumbug

+2

GTAをプレイしてダーツを飲むのが多すぎると、マルチスレッド環境で安全でないオブジェクトを使用すると世界が気に入っているように感じます。それはちょうど正常ではない。 –

答えて

1

ここでは、Parallel.ForEachコードブロック内で宣言されていない変数を変更している場合があります。その場合は、それらをロックする必要があります。

Parallel.ForEach(indexes, (index) => 
{ 

//parentCreation with index object 
lock (parent) 
{ 
    parent=create(index); 
} 


lock (childrenDefinedElseWhere) 
{ 
    //call of function to create children 
    createChildrenOfType1(parent); 
    createChildrenOfType2(parent); 
} 
}); 

ロックを使用すると、スレッドが正しく同期することが保証されます。

+1

ありがとうございます。はい、いくつかの変数は、パラレルforループから初期化されていましたが、これが矛盾の原因でした。 – Akanksha

1

標準のSystem.Collections.Generic実装はスレッドセーフではありません。

また、新しくインスタンス化された親を追加する外部コレクションParentがある場合、スレッドセーフでなければなりません。そうしないと、親インスタンスも失われる可能性があります。