繁体   English   中英

在while循环中实现Parallel.Foreach

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM