旧タイトル: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ネームスペースを使用することができます
一般に配列はスレッドセーフではないため、スレッドセーフにする必要があります。申し訳ありませんより安全です;) –
彼らは明らかにそうではありません、あなたは本当にここで何を求めていますか?それに応じてあなたのタイトルを調整します。 –
私が見ることができるところからは、ConcurrentBagを使ってほぼ90%を実行しました。それ以外の部分でConcurrentDictionaryを使用してみませんか?辞書の各キーは「スロット」になり、各キーの値はList:ConcurrentDictionary >になります。 –