When init-time, I added some values to my dictionary.
After that, I only need to TryGetValue.
in this case, I need to lock for TryGetValue?
Yes, it's thread safe if you only read it/ use TryGetValue:
Documentation:
A Dictionary<TKey, TValue> can support multiple readers concurrently,
as long as the collection is not modified. Even so, enumerating
through a collection is intrinsically not a thread-safe procedure. In
the rare case where an enumeration contends with write accesses, the
collection must be locked during the entire enumeration. To allow the
collection to be accessed by multiple threads for reading and writing,
you must implement your own synchronization.
Reading a Dictionary after population is thread safe.
Use the ConcurrentDictionary Class to ensure thread safety for use cases when you need to read and write.
From MSDN:
Represents a thread-safe collection of key/value pairs that can be
accessed by multiple threads concurrently.
Namespace:
System.Collections.Concurrent Assembly: mscorlib (in mscorlib.dll)
Link to MSDN here.
Related
I have a dictionary only supports add and modify operations and can be concurrently operated, but always for different keys. Keys are int and values are a reference type. Also modify means change some properties of a value.
My questions are:
Do I need to use ConcurrentDictionary in this scenario? If needed, how does it help?
If concurrent modification can happen on the same key, will ConcurrentDictionary help to ensure thread safty? My understanding is no, is that correct?
Thanks!
Do I need to use ConcurrentDictionary in this scenario? If needed, how
does it help?
Yes, the standard dictionary will not behave correctly if more than one thread adds or removes entries at the same time. (although it is safe for multiple threads to read from it at the same time if no others are modifying it).
If concurrent modification can happen on the same key, will
ConcurrentDictionary help to ensure thread safety? My understanding is
no, is that correct?
If you are asking "Will the concurrent dictionary prevent multiple threads from accessing the values inside the dictionary at the same time?", then no, it will not.
If you want to prevent multiple threads from accessing the same value at the same time you will need to use some sort of concurrency control, such as locking.
Best way to find this out is check MSDN documentation.
For ConcurrentDictionary the page is http://msdn.microsoft.com/en-us/library/dd287191.aspx
Under thread safety section, it is stated "All public and protected members of ConcurrentDictionary<TKey, TValue> are thread-safe and may be used concurrently from multiple threads."
So I have a Dictionary instance that I setup when the application starts. The content of this dictionary doesnt change during the lifespan of the application (as in it never gets modified, only read from).
Will I still have to keep the resource threadsafe?
Will it throw exception when two threads try to access it at the same time even though both are just reading from it and never modifying it?
BR Tomas A
No, you don't need to lock read-only resources. The purpose of locking is to check the value of a resource before writing it so that another resource can't change the value between your read and your write.
From the Dictionary<TKey, TValue> documentation, you're safe:
Thread Safety
A Dictionary<TKey, TValue> can support multiple readers
concurrently, as long as the collection is not modified. Even so,
enumerating through a collection is intrinsically not a thread-safe
procedure. In the rare case where an enumeration contends with write
accesses, the collection must be locked during the entire enumeration.
To allow the collection to be accessed by multiple threads for reading
and writing, you must implement your own synchronization.
For a thread-safe alternative, see ConcurrentDictionary<TKey, TValue>.
If you're using .Net 4.5, it would probably make sense to expose the dictionary as an IReadOnlyDictionary<TKey, TValue> to help ensure that it is used in a thread-safe manner.
You can read about the Dictionary collection here MSDN
A Dictionary can support multiple readers concurrently, as long as the collection is not modified. Even so, enumerating through a collection is intrinsically not a thread-safe procedure. In the rare case where an enumeration contends with write accesses, the collection must be locked during the entire enumeration. To allow the collection to be accessed by multiple threads for reading and writing, you must implement your own synchronization.
For a thread-safe alternative, see ConcurrentDictionary.
Public static (Shared in Visual Basic) members of this type are thread safe
Many threads have access to summary. Each thread will have an unique key for accessing the dictionary;
Dictionary<string, List<Result>> summary;
Do I need locking for following operations?
summary[key] = new List<Result>()
summary[key].Add(new Result());
It seems that I don't need locking because each thread will access dictionary with different key, but won't the (1) be problematic because of adding concurrently new record to dictionary with other treads?
Yes, you need to use locking.
Dictionary is not thread safe for add operations.
If you are on .NET 4 you may consider switching to ConcurrentDictionary. Otherwise you should create your own thread safe collection (such as this).
Consider using a ReaderWriterLockSlim for synchronizing access to your collection (in case you won't use ConcurrentDictionary).
All write accesses to your dictionnary must be locked. There is no guarantee that accessing different keys is thread safe, and, in fact, it isn't.
From MSDN:
A Dictionary can support multiple readers concurrently, as long as the collection is not modified. Even so, enumerating through a collection is intrinsically not a thread-safe procedure. In the rare case where an enumeration contends with write accesses, the collection must be locked during the entire enumeration. To allow the collection to be accessed by multiple threads for reading and writing, you must implement your own synchronization.
By default Dictionary is not thread safe. It does not matter what are you going to add. And the most important: you cannot control concurrent additions from different threads. So you need locks for sure. Or switch to a thread safe collection (i.e. CocnurrentDictionary for .NET 4+)
Which is preferred in a multi-threaded application:
Dictionary with lock object
or
Concurrency Dictionary
Which is efficient and why should I use one or the other?
edit 1: Storing Guid as key and bool as value.
edit 2: more than 2 worker threads and one UI thread.
I would say you've got the following options.
Some new Framework 4.0 classes:
ConcurrentDictionary. Work fast and reliable.
ConcurrentBag. It's unordered collection of objects, so it works faster, but suits if you don't need sorting only.
ConcurrentStack. It's an implementation of the classic LIFO (Last-In First-Out) data structure that provides thread-safe access without the need for external synchronization
ConcurrentQueue. It's a thread-safe FIFO (first in-first out) collection.
All new 4.0 classes work faster but have some features mentioned by levanovd. Performance comparison of these classes you can find here.
Some classic solutions from earlier versions:
Dictionary + Monitor. Simple wrap to lock
Dictionary + ReaderWriterLock. Better than the previous one, because has got read and write locks. So several threads can read, and just one - write.
Dictionary + ReaderWriterLockSlim. It's just optimisation of the previous one.
Hashtable. From my experience, it's the slowest method. Check Hashtable.Synchronized() method, it's a ready to go solution from Microsoft.
If I had a restriction of using Framework v3.5, I would use Dictionary + ReaderWriterLock or ReaderWriterLockSlim.
Read carefully about ConcurrentDictionary. It has some unobvious features.
Here are some of them:
If two threads call AddOrUpdate there's no guarantees about which of factory delegates will be called and even no guarantee that if a factory delegate will produce some item that this item will be stored in dictionary.
Enumerator obtained by GetEnumerator call is not a snapshot and may be modified during enumeration (that doesn't cause any exceptions).
Keys and Values properties are snapshots of corresponding collections and may not correspond to actual dictionary state.
etc.
So please read about ConcurrentDictionary again and decide if this behavior is what you need.
Hope this helps!
When you are implementing a dictionary with a lock object, your main concern seems like thread safety. So it seems, a concurrentDictionary already manages this concern. I think there is no point in re-inventing the wheel.
I think both will provide thread-safety but using a Dictionary with lock object will limit the number of thread that can access the Dictionary concurrently to 1. While using Concurrent Dictionary, you can specify concurrent level (i.e. number of threads that can access the Dictionary concurrently). If performance does matter, I believe Concurrent Dictionary should be your choice.
If I initialize a generic dictionary once, and no further adds/updates/removes are allowed, is it safe to have multiple threads reading from it with no locking (assuming that the dictionary is initialized before the readers are started)?
There is a note in the help for the non-generic HashTable that says that it is safe for multiple readers, but I did not see something similar for the Generic Dictionary.
For your future reference, the documentation is here:
http://msdn.microsoft.com/en-us/library/xfhwa508.aspx
It says:
A Dictionary
can support multiple readers
concurrently, as long as the
collection is not modified. Even so,
enumerating through a collection is
intrinsically not a thread-safe
procedure. In the rare case where an
enumeration contends with write
accesses, the collection must be
locked during the entire enumeration.
To allow the collection to be accessed
by multiple threads for reading and
writing, you must implement your own
synchronization.
Yes, it's safe if you don't modify the dictionary any more. Thread safety is only an issue in read/write scenarios