旧标题:C#中的列表数组线程是否安全? 我尝试使用列表池进行并行处理。我在数组中创建列表,然后使用ConcurrentBag的整数将它们分配给线程。由于整个代码很长,我做了一个摘录。在下面的示例中,每个线程都需要5个对象x列表。
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时,列表值会更新
请考虑我是一个业余爱好程序员,我可能会做一些明显错误的事情。任何想法如何正确地做到这一点?
的修改
基于彼得的建议,我改写如下:
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);
});
问题仍然存在。在某些情况下,列表无法更新。我做错了什么?
答案 0 :(得分:0)
您可以为线程安全集合使用System.Collections.Concurrent名称空间, and you can Use ConcurrentBag Class to Create Object(List) Pool
如果你想要池中的任何列表是线程安全的,你可以用户
var threadSafeArrayList = ArrayList.Synchronized(new ArrayList());
用于创建每个列表对象