-->

Is the ConcurrentDictionary thread-safe to the poi

2019-03-14 11:29发布

问题:

Basically, if I want to do the following:

public class SomeClass
{
    private static ConcurrentDictionary<..., ...> Cache { get; set; }
}

Does this let me avoid using locks all over the place?

回答1:

Yes, it is thread safe and yes it avoids you using locks all over the place (whatever that means). Of course that will only provide you a thread safe access to the data stored in this dictionary, but if the data itself is not thread safe then you need to synchronize access to it of course. Imagine for example that you have stored in this cache a List<T>. Now thread1 fetches this list (in a thread safe manner as the concurrent dictionary guarantees you this) and then starts enumerating over this list. At exactly the same time thread2 fetches this very same list from the cache (in a thread safe manner as the concurrent dictionary guarantees you this) and writes to the list (for example it adds a value). Conclusion: if you haven't synchronized thread1 it will get into trouble.

As far as using it as a cache is concerned, well, that's probably not a good idea. For caching I would recommend you what is already built into the framework. Classes such as MemoryCache for example. The reason for this is that what is built into the System.Runtime.Caching assembly is, well, explicitly built for caching => it handles things like automatic expiration of data if you start running low on memory, callbacks for cache expiration items, and you would even be able to distribute your cache over multiple servers using things like memcached, AppFabric, ..., all things that you would can't dream of with a concurrent dictionary.



回答2:

You still may need to use locking in the same way that you might need a transaction in a database. The "concurrent" part means that the dictionary will continue to function correctly across multiple threads.

Built into the concurrent collection are TryGetValue and TryRemove which acknowledge that someone might delete an item first. Locking at a granular level is built in, but you still need to think about what to do in these situations. For Caching, it often doesn't matter -- i.e. it's an idempotent operation.

re: caching. I feel that it depends on what you are storing in the cache + what you are doing with it. There are casting costs associated with using an object. Probably for most web based things MemCache is better suited as suggested above.