Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it correct ok to use ConcurrentBag<T> as object of ConcurrentDictionary<key, object>

In the following code:

public class SomeItem { }
public class SomeItemsBag : ConcurrentBag< SomeItem > { }
public class SomeItemsList : List< SomeItem > { }
public static class Program
{
    private static ConcurrentDictionary< string, SomeItemsBag > _SomeItemsBag;
    private static ConcurrentDictionary< string, SomeItemsList > _SomeItemsList;

    private static void GetItem(string key)
    {
        var bag = _SomeItemsBag[key];
        var list= _SomeItemsList[key];
        ...
    }
}

My assumption is that bag is threadsafe and list is not. Is this the right way to deal with a dictionary of lists in a multithreaded app?

Edited to add: Only 1 thread would be adding to the bag/list and another thread would remove, but many threads could access.

like image 345
Paul Rivera Avatar asked May 01 '12 20:05

Paul Rivera


1 Answers

Your assumptions that the ConcurrentBag is thread safe and the List is not are correct. But, you can synchronise access to the list, for example:

private static ConcurrentDictionary< string, SomeItemsBag > _SomeItemsBag;
private static ConcurrentDictionary< string, SomeItemsList > _SomeItemsList;
private static object _someItemsListLocker = new object();

private static void GetItem(string key)
{
    var bag = _SomeItemsBag[key];
    lock (_someItemsListLocker) {
        var list = _SomeItemsList[key];
    }
}

However, you're better off describing the situation completely if you want more holistic advice as to what data structure you should be using. Note that there are also ConcurrentQueue and ConcurrentStack which may be better for what you want over the list. They are optimised in multi-threaded scenarios since addition and removal can only happen on one side respectively (same sides for stack, opposite sides for queue).

like image 80
yamen Avatar answered Sep 18 '22 11:09

yamen