我有一个ConcurrentBag
暴露给Parallel.ForEach
内部的读/写操作。基本上,我需要根据几个属性检查袋子中是否存在对象,如果不存在匹配项,则将其添加到袋子中。真的,真的很慢。使用不带锁的List<>
只是时间的一小部分。此代码有什么问题?我最好使用ReaderWriterLockSlim
锁定列表吗?我在这里处理大约1,000,000个对象。
var bag = new ConcurrentBag<Beneficiary>();
Parallel.ForEach(cx, _options, line =>
{
if (!bag.Any(o =>
o.WinID == beneficiary.WinID &&
o.ProductType == beneficiary.ProductType &&
o.FirstName == beneficiary.FirstName &&
o.LastName == beneficiary.LastName &&
o.MiddleName == beneficiary.MiddleName))
{
bag.Add(beneficiary);
}
}
最佳答案
ConcurrentBag<T>
并未针对这种情况进行优化。它是使用ThreadLocal<T>
实现的,这会使您的特定用例变慢。您正在多个线程上反复遍历整个集合。遍历整个集合以检查对象是否存在也很慢。
我建议重载Beneficiary.GetHashCode
并使用ConcurrentDictionary<Beneficiary, byte>
。字节值只是可以忽略,它实际上是并发哈希集。