简体   繁体   English

如何在 C# 中创建线程安全的列表池?

[英]How do I create a pool of lists that are thread safe in C#?

Old title: Is an array of lists thread safe in C#?旧标题:列表数组在 C# 中线程安全吗?
I try to use a pool of lists for parallel processing.我尝试使用列表池进行并行处理。 I create lists in an array and then use a ConcurrentBag of integers to allocate them to threads.我在数组中创建列表,然后使用整数的 ConcurrentBag 将它们分配给线程。 Since the entire code is quite long I made an excerpt.由于整个代码很长,我摘录了一段。 In the below example each thread would need 5 lists of object x.在下面的例子中,每个线程需要 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);
});

So this runs without an error or any warnings.所以这运行没有错误或任何警告。 However inside parallel processing it sometimes fails to update values in ABCList[slot, 1....5].然而,在并行处理中,它有时无法更新 ABCList[slot, 1....5] 中的值。 By sometimes I mean 2-5 cases out of 1000. When I check in debug mode I can't reproduce the symptom.有时我的意思是 1000 个案例中的 2-5 个案例。当我在调试模式下检查时,我无法重现该症状。 When I press F11 the list values are updated.当我按 F11 时,列表值会更新。
Please consider that I'm a hobby programmer and I may do something obviously wrong here.请考虑到我是一个业余程序员,我可能会在这里做一些明显错误的事情。 Any ideas how to do this correctly?任何想法如何正确地做到这一点?
EDIT编辑
Based on the suggestion of Peter I rewrote like this:根据彼得的建议,我改写如下:

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);
});

The problem still exists.问题仍然存在。 The list fails to update in some cases.在某些情况下,列表无法更新。 What do I do wrong?我做错了什么?

You can Use System.Collections.Concurrent Name Space for Thread Safe Collections, and you can Use ConcurrentBag Class to Create Object(List) Pool您可以将 System.Collections.Concurrent 命名空间用于线程安全集合, 并且您可以使用 ConcurrentBag 类来创建对象(列表)池

if you want Any list in pool is Thread safe , you can Use如果您希望池中的任何列表都是线程安全的,您可以使用

var threadSafeArrayList = ArrayList.Synchronized(new ArrayList());

For Create each List Object对于创建每个列表对象

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM