-1

我正在尝试在 c# 中创建特定的对象池。我有两种基本方法,getObject 和 putObject 以及一个线程安全集合 - concurrentDictionary(因为需要一些键来识别池中的对象)。

但是当我从字典中删除并返回对象时,我需要重新组织这个集合,并且当我想将新对象放入集合时,我想自动递增键。有什么解决方案可以实现这一目标吗?或者任何其他可以帮助我达到相同效果并可以帮助我创建对象池的集合?(我有两个池,一个用于创建对象,但对象可以包含数据,所以我还有一些“数据池”和“数据”应该是具有一些非常量大小的对象,我需要这个“数据池”解决方案) .

或者,您是否有一些诀窍,如何使用对象制作对象池(内存池)而不是可以包含不同大小的不同数据

一些示例代码

-> Foreach 在那里,因为我想找到“数据对象”大小最接近的匹配,然后,如果有任何合适的对象,我想返回它。如果没有,我创建新的。

namespace MPool
{
    public class DataPool<T>
    {
        private ConcurrentDictionary<int,T> _objects;
        private Func<T> _objectGenerator;

        public DataPool(Func<T> objectGenerator)
        {
            if (objectGenerator == null)
                throw new ArgumentNullException("Chyba metoda objectGenerator");
            _objects = new ConcurrentDictionary<int,T>();
            _objectGenerator = objectGenerator;
        }

        public T GetObject(int size)
        {
            int diverse = Int32.MaxValue;
            T item = default(T);
            int key = -1;
            foreach (KeyValuePair<int,T> obj in _objects) {
                if (GetObjectSize(obj.Value) == size) {
                    //item = obj.Value;
                    key = obj.Key;
                    break;
                } else {
                    if (Math.Abs((GetObjectSize(obj.Value) - size)) < diverse) {
                        diverse = Math.Abs((GetObjectSize(obj.Value) - size));
                        if (diverse < (2 * GetObjectSize(obj.Value))) {
                            //item = obj.Value;
                            key = obj.Key;
                        }
                    }
                }
            }
            if (key==-1) {
                return _objectGenerator();
            } else {
                _objects.TryRemove(key, out item);
                return item;
            }
        }

        public void PutObject(T item)
        {
            //_objects.AddOrUpdate
        }

        public void Free()
        {
            while (!_objects.IsEmpty) {
                _objects.Clear();
            }
        }

        private int GetObjectSize(T TestObject)
        {
            BinaryFormatter bf = new BinaryFormatter();
            MemoryStream ms = new MemoryStream();
            byte[] Array;
            bf.Serialize(ms, TestObject);
            Array = ms.ToArray();
            return Array.Length;
        }
    }
}
4

1 回答 1

0

我对发布的代码有一个评论,它与你正在尝试做的事情没有直接关系(因为我仍然有点不确定你想要做什么),但我觉得应该解决这个问题。

在每次循环迭代中,您可能会计算对象的大小 4 次。由于您一次将这些对象添加到您的集合中,我建议您在此类中创建一个帮助类,该类可以存储对象及其大小,并在创建时计算它,然后将这些对象存储在集合中。

public DataPool<T>
{
        internal class DataStructHelper<T>
        {
            public T DataObject { get; private set; }
            public int Size { get; private set; }
            public DataStructHelper(T dataObject)
            {
                DataObject = dataObject;
                Size = GetObjectSize(dataObject);
            }

            private int GetObjectSize(T TestObject)
            {
                BinaryFormatter bf = new BinaryFormatter();
                using (MemoryStream ms = new MemoryStream())
                {
                    byte[] Array;
                    bf.Serialize(ms, TestObject);
                    return ms.ToArray().Length;
                }
            }
        }
    }
// Other code here
}

不知道您的课程将如何使用以及您计划使用多少线程等。我会考虑仅使用常规列表并锁定访问权限。您可以按排序顺序存储项目,并使用 BinarySearch 根据大小插入和搜索项目(您需要提供比较功能)。

于 2012-11-05T21:32:02.180 回答