Unable to safely lock ConcurrentDictionary value

I asked a question about this yesterday and received a lot of useful feedback (thanks!), But I don’t think I gave enough information in the question - therefore, another.

I have two threads that read two files at the same time. They put information from these files into two ConcurrentQueues. Then two more threads go, deactivate the elements from ConcurrentQueues and put the elements into one ConcurrentDictionary. When updating an item in the Dictionary, threads may need to create a new object or simply inform the current object, which receives more information. In the latter case, a long scan is sometimes required. Sometimes, after this scan, the object says OK to delete it (as an attempt to save memory), and the thread deletes it from the Dictionary.

My current (broken) code is below:

string dictionaryKey = myMessage.someValue;

Monitor.Enter(GetDictionaryLocker);
DictionaryObject currentObject = myConcurrentDictionary.GetOrAdd(dictionaryKey, new DictionaryObject());
// we can be interrupted here
lock (currentObject)
{
    Monitor.Exit(GetDictionaryLocker);
    //KeyNotFoundException is possible on line below
    if (myConcurrentDictionary[dictonaryKey].scan(myMessage)) // Scans the message - returns true if the object says its OK to remove it from the dictionary
    {
         DictionaryObject temp;                      //   It OK to delete it
         if (!queuedMessages.TryRemove(ric, out temp))   // Did delete work?
             throw new Exception("Was unable to delete a DictionaryObject that just reported it was ok to delete it");
    }
}

What's happening:

How to find the object I want in the dictionary:

DictionaryObject currentObject = myConcurrentDictionary.GetOrAdd(dictionaryKey, new DictionaryObject());

and then lock this object:

lock (currentObject)

interuppted, , , , :

if (myConcurrentDictionary[dictonaryKey].scan(myMessage))

KeyNotFoundException. - .

, , , .

  • , , ConcurrentDictionary, . , , , , , , .
  • Threading.Interlocked.CompareExchange, , , "". , - ?

, : ConcurrentQueues , - . 500 000 , O (1) ConcurrentDictionary.

?

,

+3
1

:

DictionaryItemType dictionaryItem;

if (myConcurrentDictionary.TryGetValue(dictonaryKey, out dictionaryItem))
{
    if (dictionaryItem.scan(myMessage))

, , , , .

+1

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


All Articles