2011-06-28 17 views
2

Parallel.ForEachはすべてのスレッドが戻るまでブロックしています。下の各objectTypeは実際にはリストです。このシナリオでParallel.ForEachを1回だけ使用する方法はありますか?お知らせ下さい。複数のParallel.ForEachをC#で1つにまとめる

Main(){ 
    List<Type1> objectType1 = ... 
     List<Type2> objectType2 = ... 
     List<Type3> objectType3 = ... 

    Parallel.ForEach(objectType1, MyFunction) 
    Parallel.ForEach(objectType2, MyFunction) 
    Parallel.ForEach(objectType3, MyFunction) 
} 


EDIT: これはMyFunctionのである:

MyFunction (object arg) { 

    //some code here 

    if (arg is Type1) { ProcessType1(arg as Type1); } 

    else if (arg is Type2) { ProcessType2(arg as Type2); } 

    else if (arg is Type3) { ProcessType3(arg as Type3); } 

    //some more code here 
} 
+1

それぞれの場合、「MyFunction」はすべて同じ機能ですか? –

+1

MyFunctionの型はなぜですか?それらがすべて同じタイプで動作する場合は、リストを単一のリストにまとめ、各アイテムに対してParallel.ForEachを呼び出します。 –

+1

小さなヒント: 'is'の代わりに' as'を使うと、 'var t1 = arg 'をType1とすることもできます。 if(arg!= null)ProcessType1(t1); ' –

答えて

1

interface IProcessable 
{ 
    void Process(); 
} 

class Type1 : IProcessable 
{ 
    public void Process(){ //stuff } 
} 

class Type2 : IProcessable 
{ 
    public void Process(){ //stuff } 
} 

次に、あなたはちょうどあなたがどうなるIEnumerable<IProcessable>を持っているでしょう。あなたがそれを行う方法は、Type01Type02およびType03のタイプに依存します。私はあなたがこのように行うことができますので、彼らはカスタムクラスであると仮定するつもりです:

public class X { } 
public class Y { } 
public class Z { } 

static void Main(string[] args) 
{ 
    var l1 = new List<X> { new X() }; 
    var l2 = new List<Y> { new Y() }; 
    var l3 = new List<Z> { new Z() }; 

    var master = new List<dynamic>(); 

    master.AddRange(l1); 
    master.AddRange(l2); 
    master.AddRange(l3); 

    Parallel.ForEach(master, 
     val => 
     { 
      var isX = val is X; 
     }); 
} 

あなたの問題は、同じ機能を繰り返しているなら、あなたはAction<dynamic>

Action<dynamic> action = 
    (val) => 
    { 
     var isX = val is X; 
    }; 

そして呼び出しに関数本体を格納することができます

Parallel.ForEach(yourList, action); 
6
あなたは上記の書いた擬似コードについては

Type1Type2Type3は、すべての一般的な型に変換する必要があります、メソッドのパラメータの型。それらはすべて、共通の基本型を持っている、とあなたが本当にそれらのすべてのためのMyFunctionを呼び出しているなら、あなたはLINQを使用してシーケンスを組み合わせることができます:あなたは組み合わせることができ

public void MyFunction(BaseType baseType) 
{ 
    // Process base type... 
} 
+0

あなたは共通の基本型として' object'を使うこともできますが、それはいくつかの醜いキャストです。 –

1

Parallel.ForEach(objectType1.Concat<BaseType>(objectType2).Concat(objectType3), 
    MyFunction); 

MyFunctionは次のようになりますそれらのオブジェクトにキャストすると、連結方式

List<object> combined = one.Cast<object>() 
    .Concat<object>(two.Cast<object>()) 
    .Concat(three.Cast<object>()) 
    .ToList(); 

を使用して、私もそのようにリフレクションを使用すると、おそらくいくつかの悪い設計上の決定の指標であることに注意しますs。可能であれば、異なるタイプのそれぞれが実装する共通インタフェースを抽出する必要があります。そのようなものなど:あなたはCONCATする必要が

Parallel.Foreach(listOfStuff, Process); 
関連する問題