在while循环中实现Parallel.Foreach

时间:2014-08-16 01:41:49

标签: c# foreach task-parallel-library parallel.foreach

我有一个场景,我需要在while循环中运行Parallel.Foreach。我需要了解这种实现在处理过程中的影响。我将有一个像这样的实现

 ConcurrentQueue<MyTable> queue = new ConcurrentQueue<MyTable>();

在这里,我最初在队列中添加了很多项目,但在执行时也可以在队列中添加更多项目。

while(true)
{
    Parallel.Foreach(queue, (myTable) => {some processing});
    Sleep(sometime);
}

每次一个项目将被排队并且将生成新线程以使用它,同时将添加新项目,我需要保持无限循环。

现在,我需要明白,由于并发队列是线程安全的,我认为每个项目只会被处理一次,尽管有时甚至超过foreach但我不确定是否会有多个foreach本身的线程将生成子线程或foreach的单个副本将在while循环中运行。我不知道foreach本身是如何实现的。

1 个答案:

答案 0 :(得分:3)

  

我有一个场景,我需要在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数据流,则另一种选择是使用单Parallel.Foreach()(无{{1 }}}与BlockingCollectionGetConsumingPartitioner()一起( while!)。

使用此功能时,如果没有要处理的项目,GetConsumingEnumerable()主题会被阻止,但也不会有任何处理延迟(例如由Parallel.Foreach()引起的延迟) :

Sleep()

  

我认为每件物品都会被处理一次,尽管有时甚至超过了foreach,但我不确定

这就是为什么你应该使用上述选项之一的一个原因,因为它们意味着你不需要了解它们如何工作的细节,它们只是起作用。