2011-06-28 73 views
2

Parallel.ForEach正在阻塞,直到所有線程返回。下面的每個objectType實際上是一個列表。在這種情況下,是否有任何方法可以使用Parallel.ForEach?請指教。將幾個Parallel.ForEach合併爲一個用C#

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

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


編輯: 這是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

你需要Concat的。您要採取的方式取決於Type01,Type02Type03的類型。我要假設他們是自定義類,所以你可以這樣做:

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方法的參數類型。如果他們都有一個共同的基本類型,你真的呼籲MyFunction爲所有這些,那麼你可以使用LINQ結合序列:

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

MyFunction樣子:

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

你甚至可以使用'object'作爲通用的基類型,但那是一件醜陋的事情。 –

1

你可以結合他們通過強制轉換爲對象並使用的毗連

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

我還要指出,使用這樣的反射可能是一些不好的設計決定的指示秒。如果可能的話,你應該提取一個通用的接口,每個不同類型實現。比如像:

interface IProcessable 
{ 
    void Process(); 
} 

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

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

那麼你就只需要一個IEnumerable<IProcessable>,你會怎麼做:

Parallel.Foreach(listOfStuff, Process);