【问题标题】:Implement Parallel.Foreach inside a while loop在 while 循环中实现 Parallel.Foreach
【发布时间】:2014-08-16 01:41:48
【问题描述】:

我有需要在 while 循环中运行 Parallel.Foreach 的场景。我需要了解此实现对处理方式的影响。我会有一个类似这样的实现

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

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

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

每次一个项目将被取消排队并产生新的线程来处理它,同时将添加新项目,因为我需要保持一个无限的while循环。

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

【问题讨论】:

  • 我不太确定你在问什么,但Parallel.Foreach() 会等到它的任务完成后再继续,就像它是任何简单的陈述一样。
  • 有什么问题?
  • 如果您知道何时添加新项目,则不需要无限循环来轮询新项目。
  • 如何从队列中删除已处理的项目?
  • @kingjah 我需要无限循环,因为如果没有添加任何项目并且所有正在运行的任务都已完成,则 parallel.foreach 将退出。

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


【解决方案1】:

我有需要在 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()(没有 while)与 BlockingCollectionGetConsumingPartitioner()不是 GetConsumingEnumerable()!)。

使用这个,Parallel.Foreach() 线程将在没有要处理的项目时被阻塞,但也不会在处理过程中出现任何延迟(例如由您的Sleep() 引起的延迟):

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

...

Parallel.ForEach(
    queue.GetConsumingPartitioner(), myTable => /* some processing */);

...

queue.Add(someTable);

我认为每个项目只会被处理一次,尽管在 foreach 之上,但我不确定

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

【讨论】:

  • 我有 >100 个生物识别 n/w 设备,我需要从/向它们读取/写入数据。您对上述案例有何建议。哪种方法对我的情况更有效。我在 while() 中使用了 P.For() 但是在阅读了您的帖子后,我知道我错了。所以请指教。
猜你喜欢
  • 1970-01-01
  • 2014-02-15
  • 1970-01-01
  • 1970-01-01
  • 2015-12-24
  • 2020-07-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多