开发者

Consolidate several Parallel.ForEach into one in C#

Parallel.ForEach is blocking until all threads return. Each objectType below is actually a list. Is there any way to use Parallel.ForEach just once in this scenario? Please advise.

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

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

EDIT: This is MyFunction:

MyFunction (object arg) {

    //some code here

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

开发者_Go百科    else if (arg is Type2) { ProcessType2(arg as Type2); }

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

    //some more code here
}


For the pseudo-code you've written above, Type1, Type2 and Type3 would all have to be convertible to a common type, the type of the parameter to the MyFunction method. If they all have a common base type, and you are really calling MyFunction for all of them then you can combine the sequences using LINQ:

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

and MyFunction looks like:

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


You need to concat. The way you are going to do it depends on the type of Type01, Type02 and Type03. I am going to assume they are custom classes, so you can do like this:

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;
        });
}

If your problem is repeating the same function then you can store the function body into Action<dynamic>

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

And call

Parallel.ForEach(yourList, action);


You could combined them by casting to object and using Concat

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

I would also note that using reflection like that is probably an indication of some bad design decisions. If possible you should extract a common interface that each of the different types implements. Such as something like:

interface IProcessable
{
    void Process();
}

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

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

Then you would just have an IEnumerable<IProcessable> that you would do:

Parallel.Foreach(listOfStuff, Process);
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜