2017-04-11 12 views
2

我有一個for循環編寫的手柄將項目添加到像這樣的20批次列表:C#並平行於環路與批次邏輯

for (int i = 0; i < filteredList.Count; i = i + 20) 
    { 
    newlist.Add(GetResponse(filteredList.Skip(i).Take(20))); 
    } 

這可與較小的列表精絕。所以現在我正在考慮加快處理速度,當我使用內部有10-15000個項目的較大列表來使用並行循環時?

我想是這樣的:

Parallel.For(0,filteredList.Count, i=>{ 
i+=20; 
newlist.Add(GetResponse(filteredList.Skip(i).Take(20))); 
}); 

但是,這並不讓我想要的結果......有沒有辦法做到執行比普通的for循環其他批量插入,以較快的方式,其中執行時間會比普通的for循環改進嗎?

+1

你不能做到這一點......一開始我相信newList不是線程安全的?它是什麼樣的集合類型?你也可以在將它發送到線程之前實現你的查詢...所以做.Skip()。Take()。ToList()然後通過你的循環傳遞這個LIST – Milney

+0

@Milney正確的newList不是線程安全的,我完全忘了那個......如果我使用併發包而不是列表呢? – User987

+1

@ User987爲什麼使用*任何*。您可以將其重寫爲PLINQ並將結果收集到列表中。您可以添加在PLINQ查詢中生成'filteredList'的過濾操作,並加速整個操作。 –

回答

4

List<T>線程安全,這就是爲什麼

Parallel.For(... { 
    ... 
    newlist.Add(GetResponse(filteredList.Skip(i).Take(20))); 
    ... 
    }); 

是一種錯誤的方法。嘗試使用並行LINQ(PLINQ),而不是:

newList.AddRange(filteredList 
    .AsParallel() 
    .Select((value, index) => new { 
    value = value, 
    index = index }) 
    .GroupBy(item => item.index/20) 
    .Select(chunk => GetResponse(chunk.Select(item => item.value)))); 
+1

如果您要將結果傳遞給「AddRange」,則不需要'ToList()'。另一方面,如果'newList'包含並行操作的結果,則可以將'ToList()'的結果賦值給它 –

+1

@Panagiotis Kanavos:謝謝!你很完美:'.ToList()' - 是邪惡的 –

+0

@DmitryBychenko由於某些原因,它給了我這兩行代碼的錯誤:value = value,index = index說「expected」; ? – User987