Dan*_*Dan 3 c# parallel-processing list
我正在读一本关于并行编程的书,它说它不是线程保存,不使用锁而将元素添加到列表中,因为结果将是不可预测的.例如,如果我们必须将800,000个元素添加到列表中,则最终结果将少于800 000个元素.
现在我想知道是否是线程保存从列表中读取元素.例如,假设我有一个列表BlackListedNumbers
List<int> BlackListedNumbers = new List<int> {10, 50 ....... n};
//lets say there is 500 000 elements in the list
Run Code Online (Sandbox Code Playgroud)
和另一个Numbers包含10 000 000个数字的列表,显然我将使用parallel.Foreach来完成这个任务,我想要的是Final包含所有数字Numbers的BlackListedNumbers列表不在列表中
List<int> finalList = new List<int>();
Parallel.ForEach(Numbrs,
num =>
{
if (!blackListedNumbrs.Contains(num))
{
lock (finalList)
{
finalList.Add(num);
}
}
});
Run Code Online (Sandbox Code Playgroud)
我知道这不是完成这项工作的最有效方法,但我只是想说明问题.
所以我的问题是:是否保存线程以从List中读取结果blackListedNumbrs并获得100%准确的结果?
Jon*_*eet 13
来自MSDN:
A
List<T>可以同时支持多个读取器,只要不修改集合即可.
所以如果你永远不修改列表,你应该没问题.
请注意,使用a HashSet<int>会更有效 - 并且HashSet<T>还支持多个读者1.您还可以使用Parallel LINQ使您的查询更甜美,几乎肯定更高效:
// If you want duplicates in Numbers to still come up as duplicates in the result
HashSet<int> blacklistedSet = new HashSet<int>(blackListedNumbers);
List<int> finalList = Numbers.AsParallel()
.Where(x => !blacklistedSet.Contains(x))
.ToList();
// Or if you just want a set-based operation:
List<int> finalList = Numbers.AsParallel()
.Except(blacklistedSet)
.ToList();
Run Code Online (Sandbox Code Playgroud)
好多了,不需要锁定:)
1正如评论中所述,我没有任何文件来支持这一点.但是从集合中读取不需要修改任何共享状态,所以它至少是有意义的 ......