Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Check if element exists in collection in multithreaded application

Let's assume that we have two threads and a collection:

ConcurrentDictionary<int, object[]> lists = new ConcurrentDictionary<int, object[]>();

1) One thread processes elements in collection and then remove elements from collection

foreach(object[] elem in lists.Values)
{
    //do somethind
    lists.TryRemove(key, out vals);
}

2) Second thread add elements to collection and then it need to be able to check elements status:

lists.Add(10, some_object);

...

if(lists.ContainsKey(10))
{

    //How can I be sure that at this moment element is still exists ?
    //Thread may be preempted after if() {} and second thread 
    //can remove object from collection
}
like image 591
user1475692 Avatar asked Oct 17 '13 20:10

user1475692


1 Answers

You are meant to use TryGetValue, as this makes sure the check/get is atomic:

object[] val;
if(lists.TryGetValue(10, out val)) {
    // Here you have a reference to the object[], even if it has subsequently been removed
}

Of course, the thread-safety of the object[] itself is another question, which can't be solved by ConcurrentDictionary. (For example, if say both threads modify the objects somehow, and the objects are not thread-safe, then you would need to use a lock inside the TryGetValue block.)

like image 103
McGarnagle Avatar answered Nov 13 '22 04:11

McGarnagle