2012-03-09 12 views
3

私たちのソリューションでは、要因に応じてシリアルまたはパラレルで実行できる特定のループの周りにパターンを構築したいと考えています。以下はその一般的な形です。.netパラレルとシリアルのループ

コンカレントコレクションは通常のコレクションと共通のインターフェイスを共有しないため、一般的なコードを記述するにはある種のアダプタが必要です。

具体的には、ループ本体のaddFuncデリゲートの使用について、私たちが見逃す可能性のある長期的な問題を引き起こすものがありますか?それは今のところうまくいくが、....?

Action<SomeType> addFunc; 

if(runInParallel) 
{ 
    addFunc = concurrentBag.Add; 
    loopDelegate = Parallel.ForEach; 
} 
else 
{ 
    addFunc = iList.Add; 
    loopDelegate = Serial.ForEach; // wrapper delegate for foreach 
} 

loopDelegate(source, item => 
{ 
    SomeType result = longRunningTask(item); 
    ... 
    addFunc(result); // will this 
}); 
+2

でそれはDegreeOfParallelism(シリアル用== 1)先端のためのTA、クリーナー、あまりにも、必ず –

+0

でより簡単かもしれないと同じように、あなたはそれを呼び出すことができることを意味します。 – jasper

+0

@Henk Holterman:良いアイデア、連続して実行する代替メカニズムを構築する必要はありません。 – Tudor

答えて

2

なぜTPLを.NET 4.0で使用しないのですか? http://msdn.microsoft.com/en-us/library/dd537609.aspx

TPLを開発する際に考慮した優れたホワイトペーパーがあります。.NET 4を使用できない場合は、そのペーパーを見て、そこにいくつかの勘違いを考慮する必要があります。

が明白なことを指摘するコメントに基づいて更新されました。

私はのようないくつかのシンタックスシュガーを使用したい、

ForEach<Tsource>(Predicate<IEnumerable<TSource>> isParallel, IEnumerable<TSource> source, Action<TSource> body) 
{ 
    if(isParallel(source)) 
    { 
     Parallel.ForEach<TSource>(source, body); 
    } 
    else 
    { 
     foreach (TSource element in source) 
     { 
      body(element); 
     } 
    } 
} 

は、あなたの実装を超える2つの主な利点があります。

  1. ループオーバーするアイテムを追加するために2回、実行中に2回目を列挙します。
  2. すぐには分かりませんが、Parallel.ForEachを停止し、最も効率的なゲッターをforeachが使用しないようにします。 Parallel.ForeEachは常にIEnumerableでGetEnumeratorを使用するとは限りません。列挙子が設計上並行していない場合、アイテムがIListを実装する場合、Parallel.ForEachはインデクサーを使用して列挙子がリストを反復するのを待つことなく各スレッドがソースの要素にアクセスできるようにします。 ConcurrentBagはIListを実装していません。

これは私がbtw、http://www.microsoft.com/download/en/details.aspx?displaylang=en&id=19222を参照していた論文です。

あなたがこれを組み込んでいるのなら、それは非常に良い読書ですが、特に ページ1 [5-7]、26,3 [0-2]に注意してください。

糖衣構文を使用すると、TPL、

MyParllelLibrary.ForEach((list) => true, list), item => 
{ 
    // What my code does 
}); 
+0

抽象化のパラレル版は、TPL(Parallel.ForEach)を使用していますが、完全な機能はありません。場合によっては、並列処理に外的要因があるため、シリアルモードに切り替える必要があります。これが質問の内容です。 – jasper

+0

コードを読んでください...ありがとう。 –

+0

2番目のポイントはかなり面白いです。良いですね。 – jasper

関連する問題