How do I wait before adding a value to the ConcurrentDictionary or timeout?

I have a task that needs to wait until a value is added to the ConcurrentDictionary. If a value is added, it should stop waiting and continue. It should also stop waiting if a timeout occurs (e.g. 5 seconds).

The value has to be added to the ConcurrentDictionary by another thread / task, however due to the nature of the code, I don't want the threads to communicate with each other.

How should I implement this (in C #)?

Btw I am using Tasks, not Threads for the most part, and so I'm not sure if Thread.Sleep or other methods on the current thread would be a good solution, because it might sleep with other tasks that use the same thread and cause random problems ...

+3


source to share


3 answers


I don't believe I ConcurrentDictionary

provide any hooks for this kind of thing.

You can potentially either wrap or get out ConcurrentDictionary

to provide this, but I'd be nervous about that.



The low-tech alternative is to simply poll the circle, check, and then sleep until you find the correct value or timeout. This is nowhere near great in terms of efficiency, but it is probably the simplest approach if it doesn't give you any other problems.

+1


source


I think that "waiting" for an item to be added to the collection is usually bad. Doing this generally means that the thread is blocked for a period of time. If possible, you will have to deal with timeouts. If it is not possible to define timeouts, you will have to deal with interrupting the thread to interrupt the wait (you never want to get into a situation where the thread is blocked indefinitely), for example. cancellation.



ConcurrentDictionary

is thread safe by itself; but that doesn't make all the code that uses ConcurrentDictionary

thread safe. When using an object, ConcurrentDictionary

you still need to consider thread safety requirements. ConcurrentDictionary

cannot implement these types of things. What to do when a value is added to a dictionary is also very similar - the overhead of waiting or notifying external code when new values ​​are added will result in all usesConcurrentDictionary

will be slower, even those customs that do not need to wait or do not need to be notified - so such things are not implemented. The fact that an application adds a value and needs to be notified to add a value is probably quite rare (in terms of dictionaries, why would you tell you that you just added a value ...). Thus, such an application-specific thing is usually done at the application level. that is, the fact that a parallel dictionary is being used is a coincidence and your application notifies other threads that the other thread has done what they need to know about. This could mean that wrapping is adding words with calls to the instance ManualResetEventSlim.Reset

/ Set

, and something can wait with overridingManualResetEventSlim.Wait

... Or it might just be a matter of writing an event that fires every time a value is added to the dictionary.

+1


source


This is how sleep polling could work. Fast and dirty. :)

System.Collections.Concurrent.ConcurrentDictionary<string,string> dic = new System.Collections.Concurrent.ConcurrentDictionary<string,string>();

int timeoutCount = 0;
bool hasTimedOut = false;
while (!dic.ContainsKey("KeyYouAreLookingFor"))
{
    //5 minutes has expired
    if (timeoutCount >= 10)
    {
        hasTimedOut = true;
        break;
    }

    //30 second sleep or whatever you want your poll time to be
    System.Threading.Thread.Sleep(30000);
    timeoutCount++;
}

if (hasTimedOut)
{
    //TODO: timeout code
}
else
{
    //TODO: Key has been added
}

      

-1


source







All Articles