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