Is there a general-purpose object pool for .NET?

对着背影说爱祢 提交于 2019-12-03 05:13:53

问题


I have a class that is expensive to construct, in terms of time and memory. I'd like to maintain a pool of these things and dispense them out on demand to multiple threads in the same process.

Is there a general-purpose object pool that is already tested and proven? (I don't want COM+ pooling.)


回答1:


No Cheeso, there is no general object pool like this. But it is a good idea. I think this would be pretty simple to develop. The key thing is making it work well in a threaded environment.

I think this is an interesting design problem. For example, if this needs to to scale on sever class hardware -and- you will give objects to indivudual threads often then you might do this:

  1. Keep a single central pool of objects.
  2. Keep a per-thread pool (a cache) that is populated when its called for the first time for a thread, and when it becomes empty.

This way, you avoid per-thread contention for most requests.

Different operational conditions would lead you to a different design. For example, if object allocations are rare or the number of threads is low, then it might be simpler just to have a lock around a collection. This won't scale well, but in this case, it would need to.

If you design the class or interface correctly, then you could change the implementation over time to handle more complex scenarios.




回答2:


Pulled straight from MSDN, here's an example of using one of the new concurrent collection types in .NET 4:

The following example demonstrates how to implement an object pool with a System.Collections.Concurrent.ConcurrentBag<T> as its backing store.

public class ObjectPool<T>
{
    private ConcurrentBag<T> _objects;
    private Func<T> _objectGenerator;

    public ObjectPool(Func<T> objectGenerator)
    {
        if (objectGenerator == null)
            throw new ArgumentNullException("objectGenerator");
        _objects = new ConcurrentBag<T>();
        _objectGenerator = objectGenerator;
    }

    public T GetObject()
    {
        T item;
        if (_objects.TryTake(out item))
            return item;
        return _objectGenerator();
    }

    public void PutObject(T item)
    {
        _objects.Add(item);
    }
}



回答3:


The ObjectPool class proposed by 280Z28 looks pretty good. You might also consider creating another class that implements IDisposable and wraps the return value of GetObject(). This will ensure objects are returned to your pool and reads nicely:

class ObjectPoolReference<T> : IDisposable
{
    public ObjectPool<T> Pool { get; private set; }

    public T Instance { get; private set; }

    public ObjectPoolReference(ObjectPool<T> pool, T instance)
    {
        Pool = pool;
        Instance = instance;
    }

    ~ObjectPoolReference()
    {
        Dispose();
    }

    #region IDisposable Members

    private bool _Disposed = false;

    public void Dispose()
    {
        if (!_Disposed)
        {
            Pool.PutObject(Instance);

            _Disposed = true;
        }
    }

    #endregion
}

//instance of the pool
ObjectPool<Foo> Pool;

//"using" ensures the reference is disposed at the end of the block, releasing the object back to the pool
using (var Ref = Pool.GetObject())
{
    Ref.Instance.DoSomething();
}



回答4:


Why not just write a singleton that just serves as the gateway to the array of objects that has been created.

When an object is handed out, then remove it from the available list, put it in the checked out list, and then when it is returned, reverse that.

By using a singleton for this you have a static class for everything to call, and if the expensive class is an inner class of the singleton, then nothing else can create the expensive class, and you can control how many objects to create, easily.




回答5:


Just to share. I created a generic .net common pool library using Apache Common pool as a model. http://cobrary.wordpress.com/net-common-pool-library/



来源:https://stackoverflow.com/questions/1671711/is-there-a-general-purpose-object-pool-for-net

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!