2014-10-02 70 views
-1

我正在處理+100000行並執行並行。這爲更快的處理。並行不會執行所有記錄

邏輯行爲應該是:100000記錄具有85000個groupId,意思是MyItems應該保存85000個記錄。

這是不是這樣的......我結束了不同的金額,然後85000

的過程如下:

從DB

獲取所有值

獲得所有的ID(不行ID的,而是一個的groupId)整數的數組內

過程中的groupId的

var myItems = new List<MyItem>(IDCounter.Length); 

Parallel.For(0, IDCounter.Length, (i, loopState) => 
{ 
    if(!SomeParameter) 
    loopState.Stop(); 

    var records = (from m in AllValues where m.GroupId == IDCounter[i] select m).ToList(); 

    var recordList = new List<MyRecords>(); 

    for(var j = 0; j<records.Count; j++) 
    { 
    recordList.Add(new MyRecord{Text = records[j].OtherValue}); 
    } 

    myItems.Add(new MyItem(Text = records[0].SomeValue, List = recordList)); 

}); 

有什麼想法?

+2

「myItems」的類型是什麼?如果它是'List ',那麼你可以從多個threasd訪問它,儘管它不是線程安全的。此外,這看起來像僞代碼:'new MyItem(Text = records [0] .SomeValue,List = l)'。如果您發佈*真實*代碼,這將更容易幫助您 - 理想情況下是一個簡短但完整的示例,展示問題。 – 2014-10-02 12:11:38

+0

由於您始終處理項目的完整列表,因此我無法看到這比順序算法更有效。 – Stilgar 2014-10-02 12:11:52

+0

@JonSkeet;我以爲我提供了一個簡短但可用的真實代碼,它與我所擁有的 – Schuere 2014-10-02 12:13:31

回答

2

爲了確保您不會將項目同時添加到列表中,您可以使用concurrent collection

System.Collections.Concurrent命名空間提供了應在的地方對應的類型在System.CollectionsSystem.Collections.Generic命名空間,只要多個線程同時訪問該集合使用幾個線程安全的集合類。

一個例子是使用ConcurrentBag,因爲您不能保證項目將添加到哪個訂單。

表示一個線程安全的,無序的對象集合。

另一種方法是在添加到列表中以確保在任何給定時間只添加一個項目時使用鎖定。

+0

在列表鎖定爭用成爲問題的情況下,「添加到列表時使用鎖定」的高級版本使用線程本地狀態和「finally」。 'Parallel.For'爲此提供了許多重載,其中每個線程都有自己的'List '來添加,並且它們全部放在「finally」委託內部以生成單個集合(MSDN示例:http ://msdn.microsoft.com/en-us/library/dd460703(v = vs.110)的.aspx)。 – 2014-10-02 12:15:43

+0

看起來不錯,讓我看看吧 – Schuere 2014-10-02 12:23:19

+0

@KirillShlenskiy不知道這個,會看看! – Sander 2014-10-02 12:39:51

3

您打電話myItems.Add多次同時。確保它是線程安全的。