Effective parallel assessment of the child in parallel

I have a list of objects, each of which has a bool ShouldRun () method.

I am currently repeating a list of objects and checking ShouldRun () on each object and calling Run () on the first to return true

foreach (child in Children) { if (child.ShouldRun()) { child.Run(); break; } } 

I would like to do this in parallel because the shouldRun evaluation can take a decent amount of time, and it would be helpful if the later elements in the collection would start an early evaluation.

However, I cannot think of a way to do this to satisfy these conditions:

1 Run only one item

2 Do not start a later item if the previous item is true or has not yet completed the evaluation

3 If all the “earlier” elements returned false and the middle element returned true, do not wait for the next element to complete the evaluation, because you know that it cannot redefine anything before.

I thought about doing a parallel “where” linq query to retrieve all the elements that should be Run () and then sort, but that would violate condition # 3

Ideas?

Background Information:

The system is intended for a generalized AI robotics system.

Some of the tasks with a higher priority can be launched immediately by the known sensor variables, for example: Im crashes, corrects!

other tasks can be computationally intensive (do camera image recognition and achieve visible goals)

other tasks can be databases or remotely managed (find a list of likely object locations from the database, and then go there to see if you can fall into the visible range of one of them)

Some of the tasks themselves have child tasks, which, in essence, will start this process recursively in a subset of the tasks, and the grandson's task will be transferred through the chain

+7
c # foreach parallel-processing linq
source share
4 answers

I am not a PLINQ genius, but would this be a simpler answer?

 var childToRun = Children.AsParallel().AsOrdered() .Where(x => x.ShouldRun()).FirstOrDefault(); childToRun.Run(); 
+3
source share

Just the concept of the path I would try to do this.

Run all ShouldRun() in parallel. Put the results in an ordered list along with elements and element indices (for example, IfRun () of the third element ends with false, the list will contain something like: 2, false, item).

In another thread, keep the current index starting at 0, and periodically check the ordered list. If the next index in the list is equal to the current one, process the result and advance the current index.

0
source share

You should be able to make a parallel selection with attached indexes, and then sort the result based on the index and select the first one that returns true . I do not have an IDE on this machine, so this has not been verified, but something like:

 var runnables = Children.AsParallel() .Select(child, index => new { Index = index, ShouldRun = child.ShouldRun(), Child = child }) .ToList(); //force evaluation var firstRunner = runnables.OrderBy(r => r.Index) .First(r => r.ShouldRun) //assuming at least one //else use FirstOrDefault and null-check .Child; firstRunner.Run(); 

edit: the best query for the first member is

 var firstRunner = runnables.Where(r => r.ShouldRun) // less stuff to sort later .OrderBy(r => r.Index) .First(); // no need for predicate here anymore 

edit2: this does not satisfy your condition # 3.

0
source share

I am puzzled why you have the “ShouldRun” flag for each child, instead of placing each child that you would mark “ShouldRun” in the RunThese set earlier.

Then you only need to ask if the installed RunThese size is equal or not, and if there is no zero, run them all.

[Of course, if you are going to launch them, why even mark / establish their union? You can just run them when you find that you have to run them. If you think the ShouldRun logic is expensive, then deploy it the moment you have a child to decide whether to start the child.]

0
source share

All Articles