我已经习惯在.Net的并行扩展中使用Parallel.For(),因为这是一种简单的并行化代码的方法,而无需手动启动和维护线程(这可能是繁琐的)。我现在正在看一个无限循环(做一些事情,直到我发出信号停止),我希望并行化,没有一个参数可以自由Parallel.For()重载这样做,所以想知道这里最好的方法是什么是。原则上我可以做类似的事情:
Parallel.For(0, int.Max)
但是我怀疑这可能不是工作分区逻辑要处理的预期/有效模式(?)
另一种选择是:
for(;;)
{
Parallel.For(0, 128, delegate()
{
// Do stuff.
}
}
但这似乎不够优雅,也可能导致低效的工作分区。
现在我的直觉是通过创建和维护我自己的线程来手动执行此操作,但我有兴趣获得一些反馈/意见。感谢。
=== UPDATE ===
我在接受的答案中使用了文章中的代码的简化版本(我删除了ParallelOptions参数)。这是代码......
public class ParallelUtils
{
public static void While(Func<bool> condition, Action body)
{
Parallel.ForEach(IterateUntilFalse(condition), ignored => body());
}
private static IEnumerable<bool> IterateUntilFalse(Func<bool> condition)
{
while (condition()) yield return true;
}
}
示例用法是:
Func<bool> whileCondFn = () => !_requestStopFlag;
ParallelUtils.While(whileCondFn, delegate()
{
// Do stuff.
});
答案 0 :(得分:8)
Stephen Toub有一篇关于Implementing Parallel While with Parallel.ForEach的帖子。
答案 1 :(得分:2)
如果你(真的)想要一些无限的东西,那么你可以在尽可能少的内核上使用它。 Parallel.For___
都不是一个好的选择。
您(可能)需要的是使用LongRunning选项创建的单独的线程或任务。
然后让它等待信号量,或作为最后的手段尽可能多地调用Sleep()。
答案 2 :(得分:1)
考虑到它是无限的微积分请求,但你需要在每个“循环”上都有一些finit状态,我会说我会改变一个带有外部for(;;)
循环的解决方案来执行
Parallel.ForEach(...)
呼吁对某些事件/状态进行更改。就像Monitor
信号,event
通知或类似内容......