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);
精彩评论