laimis <simulai@iit.edu> wrote:[color=blue][color=green]
> > You should lock around the checking as well - effectively make the
> > checking and potential adding atomic.
> >[/color]
>
> Actually here is how I am doing get part:
>
> public string SomeValue
> {
> get
> {
> if (cache.Contains(Key)
> return cache[Key];
> else
> {
> lock
> {
> if (cache.Contains(Key)
> return cache[Key];
> else
> cache.Add(Key, readFromConfig(Key));
> }
> }
> }
> }
>
> This way, I don't lock first time when checking the cache. So that there
> is no delay when the key exists. In the lock, I am checking again to
> make sure that the key was not added previously ...
>
> So I guess Jon you are saying this would be a fine approach? No concerns?[/color]
No, what I said was that you need a lock round the whole thing.
Locks are pretty cheap - don't risk thread safety by trying to avoid
them. There are *very* subtle concerns when it comes to using shared
data.
It's possible (according to the CLI spec) for the cache addition to
become visible to other threads before all the memory writes in
readFromConfig. This would mean it's possible for one thread to be in
the process of adding an object to the cache, and another object could
read that cache entry and see an incomplete object.
It almost certainly won't happen in the current implementation of the
CLI, but the performance gain you'll get from avoiding the lock is so
small that it's not worth the risk, IMO.
See
http://www.pobox.com/~skeet/csharp/t...latility.shtml for
more details.
--
Jon Skeet - <skeet@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too