平行的有效的foreach儿童评估
我有一个对象列表,每个对象都有一个bool ShouldRun()方法。
我正在迭代对象列表,并在每个对象上检查ShouldRun(),并在第一个对象上调用Run()以返回true
foreach (child in Children)
{
if (child.ShouldRun())
{
child.Run();
break;
}
}
我想同时做到这一点,因为评估shouldRun可能需要相当长的时间,并且让后面的元素尽早开始评估是有好处的。
然而,我想不出一种能够满足这些条件的方法:
1只运行一个项目
2如果先前的项目为真或尚未完成评估,则不要运行稍后的项目
3如果所有“较早”的项目都返回false,并且中间项目返回true,则不要等到稍后的项目才能完成评估,因为您知道它不能早先覆盖任何内容。
我想做一个并行的“where”linq查询来检索所有应该运行()然后排序的项目,但这会违反条件#3
想法?
背景信息:
该系统适用于广义机器人AI系统。
一些较高优先级的任务可以通过立即知道的传感器变量来触发,例如:Im fall over,fix it!
其他任务可能是计算密集型的(从相机进行图像识别,并接近可见目标)
其他任务可能是数据库或远程驱动(从数据库中查找可能的目标位置列表,然后在那里导航以查看是否可以进入其中一个可见范围)
一些任务本身具有子任务,这些任务本质上是要递归地在一部分任务上启动该过程,并且孙子任务将通过链传递
我不是PLINQ的天才,但是这个简单的答案不够吗?
var childToRun = Children.AsParallel().AsOrdered()
.Where(x => x.ShouldRun()).FirstOrDefault();
childToRun.Run();
只是我会尝试去做的一个概念。
并行运行所有ShouldRun()
。 将结果连同项目的项目和索引一起放入有序列表中(例如,第三项的ShouldRun()以false结束,该列表将包含如下所示的内容:2,false,项目)。
在另一个线程中,保持当前索引从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
编辑2:这并不能满足你的条件#3,但。
链接地址: http://www.djcxy.com/p/1419.html上一篇: Efficient foreach child evaluation in parallel
下一篇: GUI Pattern for showing that child is inheriting value from parent