Şafak Gür
Şafak Gür

Reputation: 7365

Unordered thread-safe collection to use as a pool?

I created a pool class that when asked, finds or initializes an item and return it to the caller. I use a ConcurrentQueue<T> as the underlying collection but I'm not sure whether it's the right type to use.

I don't need the items to be in any specific order, all I need is a thread-safe collection I can push to and pop from. Does .NET have a fast collection class for this purpose?

Edit: I used ConcurrentBag<T> after spender's answer:

public sealed class Pool<T>
{
    private readonly Func<T> initializer;

    private readonly ConcurrentBag<T> bag;

    public Pool(Func<T> initializer)
    {
        if (initializer == null)
            throw new ArgumentNullException("initializer");

        this.initializer = initializer;
        this.bag = new ConcurrentBag<T>();
    }

    public Pool(Func<T> initializer, IEnumerable<T> collection)
    {
        if (initializer == null)
            throw new ArgumentNullException("initializer");

        if (collection == null)
            throw new ArgumentNullException("initializer");

        this.initializer = initializer;
        this.bag = new ConcurrentBag<T>(collection);
    }

    public Pool(Func<T> initializer, int allocationCount)
        : this(initializer)
    {
        if (allocationCount < 0)
            throw new ArgumentOutOfRangeException("allocationCount");

        for (int i = 0; i < allocationCount; i++)
            this.bag.Add(initializer.Invoke());
    }

    public void Push(T item)
    {
        this.bag.Add(item);
    }

    public T Pop()
    {
        T item;
        return this.bag.TryTake(out item)
            ? item
            : this.initializer.Invoke();
    }
}

Upvotes: 3

Views: 432

Answers (3)

daryal
daryal

Reputation: 14929

ConcurrentBag is an unordered collection and it is thread safe.

Upvotes: 0

Nick Jones
Nick Jones

Reputation: 6493

http://msdn.microsoft.com/en-us/library/dd381779

ConcurrentBag<T> is the unordered equavalent of ConcurrentQueue<T>

Upvotes: 1

spender
spender

Reputation: 120518

ConcurrentBag sounds like just the ticket. You'll need to deal with the empty case yourself, but it seems to fit your needs quite nicely. In particular, ConcurrentBag.TryTake will grab an item from the collection with no guarantee that any particular one will be returned.

Upvotes: 5

Related Questions