2016-05-09 5 views
0

旧タイトル:C#ではリストの配列がスレッドセーフなのですか?
並列処理のためにリストのプールを使用しようとしています。私は配列のリストを作成し、整数のConcurrentBagを使ってそれらをスレッドに割り当てます。コード全体がかなり長いので、私は抜粋をしました。以下の例では、各スレッドはオブジェクトxの5つのリストを必要とします。 C#でスレッドセーフなリストを作成するにはどうすればよいですか?

int maxThreads = 64; 
ConcurrentBag<int> pool = new ConcurrentBag<int>(); 
// Populate ConcurrentBag with values 0 through 63 
for (int i = 0; i <= maxThreads - 1; i++) 
{ 
    pool.Add(i);   
} 
List<x>[,] ABCList = new List<x>[maxThreads, 5]; 
Parallel.ForEach(zList, 
new ParallelOptions { MaxDegreeOfParallelism = maxThreads }, 
p => 
{ 
    while (!pool.TryTake(out slot)); 
    // Do something here with ABCList[slot, 1....5] 
    // Example: ABCList[slot, 1].[1].Field1 = 2; 
    // Example: ABCList[slot, 1].[1].Field2 = "abc"; 
    pool.Add(slot); 
}); 

これはエラーまたは警告なしで実行されます。しかし、並列処理の中では、ABCList [slot、1 .... 5]の値を更新できないことがあります。時々私は1000人のうち2〜5人を意味します。私がデバッグモードでチェックインするとき、私はその症状を再現することができません。 F11キーを押すと、リストの値が更新されます。
私は趣味のプログラマーだと考えてください。私は明らかに間違ったことをしています。どのようにこれを正しく行うにはどのようなアイデアですか?
ピーターの提案に基づいて、EDIT
私はこのように書き直し:

int maxThreads = 64; 
ConcurrentBag<int> pool = new ConcurrentBag<int>(); 
ConcurrentDictionary <int, List<x>[]> ABCList = new ConcurrentDictionary<int, List<x>[]>(); 
// Initialize ConcurrentDictionary 
for (int i = 0; i < maxThreads; i++) 
{ 
    pool.Add(i); 
    ABCList[i] = new List<x>[5]; 
    for (int w = 0; w <= 4; w++) 
    { 
      ABCList[i][w] = templateABCList[w].ConvertAll(p => p); 
    } 
} 
Parallel.ForEach(zList, 
new ParallelOptions { MaxDegreeOfParallelism = maxThreads }, 
p => 
{ 
    while (!pool.TryTake(out slot)); 
    // Do something here with ABCList[slot][1...5] 
    // Example: ABCList[slot][1][1].Field1 = 2; 
    // Example: ABCList[slot][1][1].Field2 = "abc"; 
    pool.Add(slot); 
}); 

を問題がまだ存在します。リストが更新されない場合があります。何が間違っていますか?

あなたがプール内の任意のリストは、スレッドセーフである場合は、あなたが(ユーザー

VAR threadSafeArrayList = ArrayList.Synchronizedでき and you can Use ConcurrentBag Class to Create Object(List) Pool

、スレッドセーフコレクションのためにSystem.Collections.Concurrentネームスペースを使用することができます

+0

一般に配列はスレッドセーフではないため、スレッドセーフにする必要があります。申し訳ありませんより安全です;) –

+1

彼らは明らかにそうではありません、あなたは本当にここで何を求めていますか?それに応じてあなたのタイトルを調整します。 –

+0

私が見ることができるところからは、ConcurrentBagを使ってほぼ90%を実行しました。それ以外の部分でConcurrentDictionaryを使用してみませんか?辞書の各キーは「スロット」になり、各キーの値はList :ConcurrentDictionary >になります。 –

答えて

0

新しいArrayList());

各リストオブジェクトを作成するには

関連する問題