Returning a dictionary in C # in a multi-threaded environment

I announced a dictionary of dizianaria:

Dictionary<String, Dictionary<String, String>> values; 

I have a getter to get a dictionary at a specific index:

 public Dictionary<String,String> get(String idx) { lock (_lock) { return values[moduleName]; } } 

As you can see, I work in a multi-threaded environment. My question is: I need to return a copy of my dictionary in order to be thread safe:

 public Dictionary<String,String> get(String idx) { lock (_lock) { return new Dictionary<string, string>(values[moduleName]); } } 

If I donโ€™t, the class calling getter will get a copy (so if I remove this dictionary from my Dictionary<String, Dictionary<String, String>> , will it still work)?

Greetings

Thierry.

+6
source share
3 answers

If you really need to return the dictionary itself, then you will need to either have rules for how the threads are blocked on it (fragile, what if there is a case that does not do this?), Use it in the read-only way (the dictionary is thread safe is read-only, but note that this assumes that the code closed to the class no longer writes for it) use a threadlike dictionary ( ConcurrentDictionary uses striped lock, my ThreadSafeDictionary uses loose approaches, and there are different scenarios in which one of them excellent IT, etc.), or make a copy, as you suggest.

Otherwise, if you set a method for extracting or setting the final string found by two keys, for listing the second-level keys found by the key, and so on, then you can not only control the lock performed in one place, but it got other advantages in the cleanliness of the interface and the release of the implementation from the interface (for example, you could switch from locking to using a thread-like dictionary or vice versa, without affecting the call code).

+4
source

Dictionary<> not thread safe, but ConncurrentDictionary<> is.

The class that calls the getter gets a link, which means that it will still be there if you remove it from values -Dictionary, since the GC does not clear it, if you have a link somewhere, you just canโ€™t get it with getter.

This basically means that you have two options when using Dictionary<> :

  • return a copy . This is a bad idea because if you change the configuration, you have two different configurations in your application "live".
  • lock instance : this will make it thread safe, but then use ConcurrentDictionary<> , as it does just that for you
+6
source

If you do not return the copy, the caller will be able to change the dictionary, but this is not a thread safety issue.

There is also a thread safety issue because you do not detect locks to synchronize read and write. For example, your writer thread may add / remove a value while the reader thread is working with the same instance.

Yes, you must return a copy.

+2
source

Source: https://habr.com/ru/post/906735/


All Articles