ObjectPool的< T>或类似的.NET已经在图书馆? [英] ObjectPool<T> or similar for .NET already in a library?

查看:229
本文介绍了ObjectPool的< T>或类似的.NET已经在图书馆?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我不想写我自己,因为我怕我会想念的东西和/或撕掉别人的作品,所以有存在的.NET库中的ObjectPool的(或类似)班?

I don't want to write my own because i'm afraid i might miss something and/or rip off other people's work, so is there an ObjectPool (or similar) class existing in a library for .NET?

通过对象池,我的意思是,协助这需要很长的时间来创建对象的缓存类,一般用来提高性能。

By object pool, i mean a class that assists caching of objects that take a long time to create, generally used to improve performance.

推荐答案

更​​新:

我还提出了 BufferBlock< T> 从TPL数据流。 IIRC它的.Net的一部分了。 T> 是,你可以等待异步的项目使用的 BufferBlock&LT伟大的事情-us /库/ hh194836.aspx相对=nofollow> 帖子< T> 和的 ReceiveAsync< T> 的扩展方法。 pretty的得心应手异步/等待世界。

I'd also put forward BufferBlock<T> from TPL DataFlow. IIRC it's part of .net now. The great thing about BufferBlock<T> is that you can wait asynchronously for items to become available using the Post<T> and ReceiveAsync<T> extension methods. Pretty handy in an async/await world.

原来的答案

前阵子我遇到这个问题,并想出了一个轻量级(rough'n'ready)线程(我希望)池已经证明是非常有用的,可重复使用的和强大的:

A while back I faced this problem and came up with a lightweight (rough'n'ready) threadsafe (I hope) pool that has proved very useful, reusable and robust:

    public class Pool<T> where T : class
    {
        private readonly Queue<AsyncResult<T>> asyncQueue = new Queue<AsyncResult<T>>();
        private readonly Func<T> createFunction;
        private readonly HashSet<T> pool;
        private readonly Action<T> resetFunction;

        public Pool(Func<T> createFunction, Action<T> resetFunction, int poolCapacity)
        {
            this.createFunction = createFunction;
            this.resetFunction = resetFunction;
            pool = new HashSet<T>();
            CreatePoolItems(poolCapacity);
        }

        public Pool(Func<T> createFunction, int poolCapacity) : this(createFunction, null, poolCapacity)
        {
        }

        public int Count
        {
            get
            {
                return pool.Count;
            }
        }

        private void CreatePoolItems(int numItems)
        {
            for (var i = 0; i < numItems; i++)
            {
                var item = createFunction();
                pool.Add(item);
            }
        }

        public void Push(T item)
        {
            if (item == null)
            {
                Console.WriteLine("Push-ing null item. ERROR");
                throw new ArgumentNullException();
            }
            if (resetFunction != null)
            {
                resetFunction(item);
            }
            lock (asyncQueue)
            {
                if (asyncQueue.Count > 0)
                {
                    var result = asyncQueue.Dequeue();
                    result.SetAsCompletedAsync(item);
                    return;
                }
            }
            lock (pool)
            {
                pool.Add(item);
            }
        }

        public T Pop()
        {
            T item;
            lock (pool)
            {
                if (pool.Count == 0)
                {
                    return null;
                }
                item = pool.First();
                pool.Remove(item);
            }
            return item;
        }

        public IAsyncResult BeginPop(AsyncCallback callback)
        {
            var result = new AsyncResult<T>();
            result.AsyncCallback = callback;
            lock (pool)
            {
                if (pool.Count == 0)
                {
                    lock (asyncQueue)
                    {
                        asyncQueue.Enqueue(result);
                        return result;
                    }
                }
                var poppedItem = pool.First();
                pool.Remove(poppedItem);
                result.SetAsCompleted(poppedItem);
                return result;
            }
        }

        public T EndPop(IAsyncResult asyncResult)
        {
            var result = (AsyncResult<T>) asyncResult;
            return result.EndInvoke();
        }
    }

为了避免汇集对象的任何接口要求,二者的创建和对象的复位是由用户提供的代表进行的:即

In order to avoid any interface requirements of the pooled objects, both the creation and resetting of the objects is performed by user supplied delegates: i.e.

Pool<MemoryStream> msPool = new Pool<MemoryStream>(() => new MemoryStream(2048), pms => {
        pms.Position = 0;
        pms.SetLength(0);
    }, 500);

在这种情况下,该池是空的,BeginPop / EndPop对提供的APM(ISH)指(用杰夫·里希特的优秀的 AsyncResult&LT; TResult&GT; 实现)

我不太记得它为什么constained为T:类...有可能是无

I can't quite remember why it is constained to T : class... there's probably none.

这篇关于ObjectPool的&LT; T&GT;或类似的.NET已经在图书馆?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆