同时有效地预测儿童的评估

时间:2010-06-26 22:18:57

标签: c# linq foreach parallel-processing

我有一个对象列表,每个对象都有一个bool ShouldRun()方法。

我正在迭代对象列表,并检查每个对象上的ShouldRun(),并在第一个上调用Run()返回true

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

我想并行执行此操作,因为评估shouldRun可能需要相当长的时间,并且让集合中的后续元素尽早开始评估是有利的。

然而,我想不出一种能满足这些条件的方法:

1只运行一个项目

2如果之前的项目为真,或者尚未完成评估

,请不要运行以后的项目

3如果所有“早期”项目都返回false,并且中间项目返回true,则不要等待后面的项目完成评估,因为您知道它不能先覆盖任何内容。

我想做一个并行的“where”linq查询来检索所有的项目,然后运行shouldRun()然后排序,但这会违反条件#3

想法?

背景资料:

该系统适用于通用机器人AI系统。

一些较高优先级的任务可以通过立即知道的传感器变量触发,例如:我摔倒,修复它!

其他任务可能是计算密集型的(从相机进行图像识别,并接近可见目标)

其他任务可能是数据库或远程驱动(从数据库中查找可能的目标位置列表,然后在那里导航以查看是否可以进入其中一个的可见范围)

某些任务本身有子任务,本质上是在一个任务子集上递归启动这个过程,而孙子任务将通过链传递

4 个答案:

答案 0 :(得分:3)

我不是PLINQ的天才,但这个简单的答案不会足够吗?

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

答案 1 :(得分:0)

只是我试图这样做的概念。

并行运行所有ShouldRun()。将结果与项目的项目和索引一起放入有序列表(例如,第三项的ShouldRun()以false结尾,列表将包含如下内容:2,false,item)。

在另一个线程中,保持当前索引从0开始并定期检查有序列表。如果列表中的下一个索引等于current,则处理结果并提前当前索引。

答案 2 :(得分:0)

您应该能够在附加索引的情况下进行并行选择,然后根据索引对结果进行排序,并选择返回true的第一个结果。我在这台机器上没有IDE,所以这是未经测试的,但是类似于:

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

编辑:更好地查询第一个跑步者 -

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

edit2:但这并不能满足你的条件#3。

答案 3 :(得分:0)

我很困惑为什么你在每个孩子身上都有一个“ShouldRun”标志,而不是早先将每个孩子都标记为“ShouldRun”到“RunThese”套装中。

然后你只需询问RunThese的设定大小是否为零,如果不是零,则全部运行。

[当然,如果你打算运行它们,为什么甚至标记/设置联合它们?当你发现应该运行它们时,你可以启动它们。如果您认为ShouldRun逻辑是昂贵的,那么在您让孩子决定是否应该管理孩子的那一刻就分叉。]