Is Dictionary<KeyType,ValueType> thread safe to read and iterate through values?

That is, writing to this Dictionary will not be (initialized only when the project is launched), and I want to understand whether it can be used in the context of a singleton service in ASP.NET Core 2.0?

    2 answers 2

    https://msdn.microsoft.com/en-us/library/xfhwa508(v=vs.110).aspx

    Thread safety

    A dictionary can support multiple readers as it is.

    i.e

    Thread safety

    ... supports several simultaneous read operations, as long as the data does not change.

    • This confuses me here >> Even so, not a thread-safe procedure. - Dmitry Polyanin
    • I believe that this refers to the brute force, during which the dictionary changes. - Igor
    • In theory, it should be ... but the text does not seem to have words that it refers specifically to enumeration with changes, it seems that for any sorting. - Dmitry Polyanin
    • Although there goes further decoding, and it seems like what you wrote is explained. - Dmitry Polyanin

    See, the dictionary itself is thread-safe for the case when you only have read operations from different threads. However, for the case when you still need initialization, it is necessary to take into account possible “races” between the initializing stream and the stream that reads the already initialized dictionary.

    Consider this code:

     var dict = Dictionary<K, V>(); dict[k1] = v1; // инициализация GlobalAccessibleDict = dict; // публикация 

    I read through the specification and did not find a clause that would prevent the compiler from rearranging initialization and publishing, because from the point of view of the publishing flow from rearranging these assignments, the meaning of the code does not change. Thus, from the point of view of another reading thread, initialization may occur too late . So, apparently, from the point of view of the language, this pattern is incorrect , and can lead to another thread reading the unde-initialized dictionary. In order to be sure, you must use lock (or, perhaps, publication through a volatile-field).

    On the other hand, from the point of view of implementation in Microsoft .NET, the article Joe Duffy CLR 2.0 memory model states that in the implementation of .NET 2.0

    Rule 2: It can move after one.

    that is, permutations of records into variables are not allowed. If I correctly understood this text, it means that the race described by me is impossible, and initialization will end strictly before publication. Therefore, with a good degree of probability in the current implementation (and the .NET 4.0 memory model seems to be no weaker) everything is fine in your approach. (I did not find, however, anything about the order of updating data in other threads, so that the subtleties remain.)

    • I may still have a situation of re-initialization of the dictionary. If it's easier, I store the roles in the dictionary and they are in memory all the time (it makes no sense to explain why). But the admin can change roles, so I will need to reinitialize them. I thought about it today too. But here, too, there shouldn't be any problems, since I’ll just create a new dictionary and write it over what was originally, and new requests will go to a new dictionary, while if the old ones are still processing something, there will be old values, it’s me arranges. - Dmitry Polyanin
    • Regarding the fact that you wrote, I understood, but in my case there should not be a problem, since initialization and publication occurs when the site is launched, and calls are already guaranteed to come later. - Dmitry Polyanin
    • Hmm ... why should the compiler change the order of operations, if it can lead to such problems ... - Dmitry Polyanin
    • @DmitryPolyanin: If the dictionary changes, then you just can not do without blocking. Surround access to changing parts of the lock 'om. - VladD
    • @DmitryPolyanin: No, I think you did not understand. The fact that one action is later than another in time does not guarantee that the data will be visible in another stream. Do you imagine that the data "slowly fly" into another stream, and in a couple of seconds they will fly right through. This is not true. There is no such guarantee in the specification. - VladD