【问题标题】:Auto-increment dictionary key in c#c#中的自增字典键
【发布时间】:2012-11-05 20:50:32
【问题描述】:

我正在尝试在 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、2、3、4、5”然后用键“3”删除了项目,那么项目4和5将分别移动到3和4,因此现在有键“1 , 2, 3, 4" 和下一个键是 5 而不是 6?
  • 自动增加密钥并重新组织集合?列表不是您要找的吗?它有索引,当你删除一个项目时它会重新组织。
  • pstrjds,这正是我的意思。我有一些代码,但它可能很奇怪,因为我第一次做这样的事情。列表可以提供帮助,但我认为它没有线程安全的替代方案。
  • 那么这些键是否只是用于连接对象集合和对象可能持有的数据?另外,非常量大小的“数据”是字节流还是类似的东西?

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


【解决方案1】:

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

在每次循环迭代中,您可能会计算对象的大小 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 根据大小插入和搜索项目(您需要提供比较功能)。

【讨论】:

  • 谢谢,如果在集合中没有合适大小的对象,那么创建新对象怎么办?
  • 应在将数据放入集合的 PutObject 方法中调用此代码。当您在 GetObject 中返回一个对象时,您将从集合中删除,因此该结构在那里将无用。
猜你喜欢
  • 2012-01-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-02-09
  • 2011-01-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多