Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the best way of adding/removing a specific item from List<T> in multi-threading scenario

Tags:

c#

concurrency

I have now a scenario that needs to add and remove items in multi-threading condition

I'm doing

lock(list)
{
    if(!list.Contains(item))
    {
        list.Add(Item);
    }
}

and

lock(list)
{
    if(list.Contains(item))
    {
        list.Remove(Item);
    }
}

But I have now a very big problem with race condition. The lock time is increasing and incrasing.

I wished I could use ConcurrentBag but it doesn't has Contains Method, so I can't remove the specific item I want to remove.

I'm now using ConcurrentDicionary as a temporary solution. but it's definitely not the proper way to do it.

So my question is how can I solve this problem? Is there any lock free implementation for things like this out there? Because none of the Collections under Concurrent name space suit for this problem.

like image 379
liiir1985 Avatar asked Nov 09 '11 14:11

liiir1985


1 Answers

What you want is a concurrent version of HashSet<T>. ConcurrentBag<T> wasn't meant for that, it's for support of efficient producer-consumer scenarios. There isn't any such collection in the Framework.

So, you could use ConcurrentDictionary<Item, Item>, as you said. But I agree with you that it's not an ideal solution.

Or, you could replace your locking code that uses List<T> with one that uses HashSet<T>. Operations like Contains() and Remove() can be very slow on large lists. But they should be fast in hash sets, which should improve your performance significantly, if your collection is large enough.

It's also possible there is some third-party library that contains something like ConcurrentHashSet<T>, but I don't know about any.

like image 139
svick Avatar answered Oct 17 '22 14:10

svick