我在ConcurrentDictionary
循环中填充Parallel.ForEach
:
var result = new ConcurrentDictionary<int, ItemCollection>();
Parallel.ForEach(allRoutes, route =>
{
// Some heavy operations
lock(result)
{
if (!result.ContainsKey(someKey))
{
result[someKey] = new ItemCollection();
}
result[someKey].Add(newItem);
}
}
如何在不使用lock语句的情况下以线程安全的方式执行最后的步骤?
编辑:假设ItemCollection
是线程安全的。
答案 0 :(得分:4)
我认为您需要GetOrAdd
,明确设计用于获取现有项目,或者如果给定密钥没有条目,则添加新项目。
var collection = result.GetOrAdd(someKey, _ => new ItemCollection());
collection.Add(newItem);
如问题评论中所述,这假设ItemCollection
是线程安全的。
答案 1 :(得分:1)
您需要使用GetOrAdd
方法。
var result = new ConcurrentDictionary<int, ItemCollection>();
int someKey = ...;
var newItem = ...;
ItemCollection collection = result.GetOrAdd(someKey, _ => new ItemCollection());
collection.Add(newItem);
答案 2 :(得分:1)
假设ItemCollection.Add
不是线程安全的,将需要锁定,但可以减少关键区域的大小。
var collection = result.GetOrAdd(someKey, k => new ItemCollection());
lock(collection)
collection.Add(...);
更新:因为它似乎是线程安全的,所以你根本不需要锁定
var collection = result.GetOrAdd(someKey, k => new ItemCollection());
collection.Add(...);