c#中自动增加字典键

时间:2012-11-05 20:50:33

标签: c# dictionary thread-safety auto-increment pool

我正在尝试在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;
        }
    }
}

1 个答案:

答案 0 :(得分: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根据大小插入和搜索项目(您需要提供比较功能)。