[英]Implement Parallel.Foreach inside a while loop
我有一个场景,我需要在while循环中运行Parallel.Foreach。 我需要了解这种实现在处理过程中的影响。 我将有一个像这样的实现
ConcurrentQueue<MyTable> queue = new ConcurrentQueue<MyTable>();
在这里,我最初在队列中添加了很多项目,但在执行时也可以在队列中添加更多项目。
while(true)
{
Parallel.Foreach(queue, (myTable) => {some processing});
Sleep(sometime);
}
每次一个项目将被排队并生成新线程以使用它,同时将添加新项目,我需要保持无限循环。
现在,我需要了解,因为并发队列是线程安全的,我认为每个项目只会被处理一次,尽管有时甚至超过foreach但我不确定是否会有多个foreach本身的线程将会产生子线程或foreach的单个副本将在while循环中运行。 我不知道foreach本身是如何实现的。
我有一个场景,我需要在while循环中运行Parallel.Foreach。
我不认为你这样做。 你想要并行处理新项目,但我认为这不是最好的方法。
我认为最好的方法是使用TPL Dataflow的ActionBlock
。 当没有要处理的项目时,它不会浪费CPU或线程,如果您设置其MaxDegreeOfParallelism
,它将并行处理项目:
ActionBlock<MyTable> actionBlock = new ActionBlock<MyTable>(
myTable => /* some processing */,
new ExecutionDataflowBlockOptions
{
MaxDegreeOfParallelism = DataflowBlockOptions.Unbounded
});
...
actionBlock.Post(someTable);
如果您不想或不能(仅限.Net 4.5)使用TPL Dataflow,另一个选项是使用单个Parallel.Foreach()
(不会while
)和BlockingCollection
以及GetConsumingPartitioner()
( 不是 GetConsumingEnumerable()
!)。
使用它时,如果没有要处理的项目,则会阻止Parallel.Foreach()
线程,但处理中也不会有任何延迟(如Sleep()
引起的延迟):
BlockingCollection<MyTable> queue = new BlockingCollection<MyTable>();
...
Parallel.ForEach(
queue.GetConsumingPartitioner(), myTable => /* some processing */);
...
queue.Add(someTable);
我认为每件物品都会被处理一次,尽管有时甚至超过了foreach,但我不确定
这就是为什么你应该使用上面的一个选项的一个原因,因为它们意味着你不需要了解它们如何工作的细节,它们只是起作用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.