在C#中将几个Parallel.ForEach合并为一个

时间:2011-06-28 00:37:51

标签: c# multithreading

Parallel.ForEach阻塞,直到所有线程都返回。下面的每个objectType实际上都是一个列表。在这种情况下,有没有办法只使用Parallel.ForEach一次?请指教。

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
}

3 个答案:

答案 0 :(得分:6)

对于您上面写的伪代码,Type1Type2Type3都必须可以转换为公共类型,MyFunction的参数类型{1}}方法。如果它们都有一个共同的基类型,并且你真的为所有它们调用MyFunction,那么你可以使用LINQ组合序列:

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

MyFunction看起来像:

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

答案 1 :(得分:1)

您可以通过强制转换为对象并使用Concat

来组合它们
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);

答案 2 :(得分:1)

你需要连接。您的方式取决于Type01Type02Type03的类型。我将假设它们是自定义类,所以你可以这样做:

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