I love ConcurrentDictionary!
Not just because it is concurrent, because of this wonderful method:
public class Storage : IStorage { private readonly ConcurrentDictionary<Guid, ConcurrentDictionary<int, List<object>>> values = new ConcurrentDictionary<Guid, ConcurrentDictionary<int, List<object>>>(); public void Store(Guid taskId, int level, object value) { values.GetOrAdd(taskId, guid => new ConcurrentDictionary<int, List<object>>()) .GetOrAdd(level, i => new List<object>()) .Add(value); } }
Doing this with Dictionary is always a pain, but this is an extremely natural way of doing things.
Comments
That's awesome. You could do this with regular dictionaries, by adding an extension method to IDictionary <tkey,> , like this:
static TValue GetOrAdd <tkey,> (this IDictionary <tkey,> collection, TKey key, Func <tkey,> generator)
{
TValue value;
if (!collection.TryGetValue(key, out value))
return value;
}
Your commenting system apparently doesn't escape less-than and greater-than. Second attempt:
static TValue GetOrAdd<TKey, TValue>(this IDictionary<TKey, TValue> collection, TKey key, Func<TKey, TValue> generator)
{
TValue value;
if (!collection.TryGetValue(key, out value))
return value;
}
That is a pretty useful function!
Dam, why did I not think of writing one like that. I do have a similar one I use for caches.
For example:
return cache.GetWithAdd("admembers", () => GetADMemberListRemote());
You'd need some form of locking to make it thread safe, e.g.
TValue value;
lock (collection)
{
if (!collection.TryGetValue(key, out value))
collection.Add(key, value = generator(key));
}
return value;
And of course this doesn't preclude someone bypassing the lock by directly doing collection.Add
Yea some of the first extension methods I wrote were to deal with dictionaries. If theres nothing special about the way you construct the value, you can simplify slightly:
public static TValue GetOrAddDefaultValue<TKey, TValue>(this IDictionary<TKey, TValue> dictionary, TKey key) {
}
Shouldn't you use some concurrent datatype for the list as well?
Although it is beside your point you use a single dictionary with a tuple as the key.
This looks something like Redis ( http://code.google.com/p/redis/ ), which I just happen to be building some .Net client software for here: http://code.google.com/p/redisdotnet/
That allows a vast number of atomic thread-safe actions to be done on a remote dictionary.
Comment preview