我有一个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>。字节值只是可以忽略,它实际上是并发哈希集。

10-06 14:16