Can you use a ConcurrentDictionary for one-to-many mapping?
I have a mapping where each key could have multiple associated values. I thought that a ConcurrentDictionary might help me more easily code this map for use in a multithreaded environment, but the methods seem to be built around a single value. I see that AddOrUpdate() 开发者_开发技巧lets me modify the value if it already exists, but it doesn't guarantee atomicity for that operation so it seems pointless? Does anyone have a good strategy for tackling this situation?
Sorry, I guess I was being a bit vague. I'd like to have multiple values for a key, ie have an IList associated with the key. But I want to be able to add/remove values from the multi-value in a safe manner. It just looked like the AddOrUpdate + delegate method might result in things getting lost if multiple calls to it were made at the same-ish time?
I thought that AddOrUpdate
was atomic, but it looks like it's not atomic with regard to the delegate. Sorry!
A reference that might help: http://blogs.msdn.com/b/pfxteam/archive/2009/11/06/9918363.aspx
It looks like both AddOrUpdate
and TryUpdate
will work.
edit
I may well be mistaken. If so, I don't think the documentation is clear enough to say, so let's just look at the code. Courtesy of reflector:
public TValue AddOrUpdate(TKey key, Func<TKey, TValue> addValueFactory, Func<TKey, TValue, TValue> updateValueFactory)
{
TValue local;
TValue local3;
if (key == null)
{
throw new ArgumentNullException("key");
}
if (addValueFactory == null)
{
throw new ArgumentNullException("addValueFactory");
}
if (updateValueFactory == null)
{
throw new ArgumentNullException("updateValueFactory");
}
do
{
if (!this.TryGetValue(key, out local3))
{
TValue local2;
local = addValueFactory(key);
if (!this.TryAddInternal(key, local, false, true, out local2))
{
continue;
}
return local2;
}
local = updateValueFactory(key, local3);
}
while (!this.TryUpdate(key, local, local3));
return local;
}
Now, if the update factory took an existing list and returned a new one with an additional member, it does indeed look to me as though it will be atomic. In the event of a race condition, the loser will simply have their update factory called again. Am I mistaken?
精彩评论