4

我有一個像[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]這樣的有序列表。我將它傳遞給Parallel.ForEach聲明。我可以以某種方式實現以下執行存儲桶的順序:處理前3個項目[1, 2, 3],其中存儲桶本身的排序不是必需的,例如可以是[2, 1, 3]。然後處理下3項[4, 5, 6]等?有序並行執行

+0

你是說你想洗牌每批3個元素? – tinstaafl

+0

不,我說的是批量訂購:前3個,然後是下3個,但裏面的訂單可能是隨機的 - 不是強制性的在水桶內訂購 –

回答

5

我不確定您是否可以直接進行此操作。但我建議您將輸入列表分成較小的列表,然後您可以使用Parallel.Foreach處理每個子列表。

List<int> fruits = new List<int>() { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; 
List<List<int>> ls = new List<List<int>>(); 
for (int i = 0; i < fruits.Count; i += 3) 
{ 
    ls.Add(fruits.GetRange(i, Math.Min(3, fruits.Count - i))); 
} 
foreach (List<int> group in ls) 
{ 
    Parallel.ForEach(group, fruit => 
    { 
    }); 
} 

3是小列表的長度。

+0

你確定這會起作用嗎?讓我試試 –

+1

@GiorgiNakeurl我將會建議一些類似的東西 - 請記住,Parallel.ForEach的Microsoft文檔明確聲明它們不保證特定的執行順序,所以你幾乎不得不做這樣的事情。 – EJoshuaS

+0

嗯,這個工程。我想試試這個,但我不相信它會工作:) –

2

即使接受的答案完全符合要求,它也會有一些開銷。首先,當我們談論TPL時,數據陣列的體積可能很大,所以簡單地創建這麼多的陣列非常耗費內存。
此外,@viveknuna建議的解決方案不保證塊的順序。如果它是好的,你應該使用來自@DmitryBychenko答案的小更新:

const int chunkSize = 3; 
var array = Enumerable.Range(1, 9).ToArray(); 
// get the chunks for indexes for array sized in group of 3 
var partitioner = Partitioner.Create(0, array.Length, chunkSize); 

// use all the system resources 
var parallelOptions = new ParallelOptions { MaxDegreeOfParallelism = Environment.ProcessorCount }; 

// use the partitioner for a chunks, so outer parallel foreach 
// will start a task for all the chunks, [1, 2, 3], [4, 5, 6], [7, 8, 9] 
Parallel.ForEach(partitioner, parallelOptions, part => 
    { 
     // inner foreach will handle part of the chunk in parallel 
     Parallel.ForEach(array.Skip(part.Item1).Take(chunkSize), parallelOptions, value => 
      { 
       // handle the array value in parallel 
      }); 
    }); 

在給定的代碼,如果你設置了ParallelOptions.MaxDegreeOfParallelism1,你會得到期望的有序並行執行,塊大塊。

+0

謝謝,明天我會試一試。 –