簡體   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