如何从池中检索不同的对象?

时间:2012-02-08 09:47:19

标签: c# c#-4.0

我需要在对象池中存储三种不同类型的对象,并且需要根据需要进行检索。

我尝试用Queue实现它,但我只能用一种类型来实现它。

是否可以在对象池中存储和检索不同类型的对象?如何?

4 个答案:

答案 0 :(得分:2)

考虑使用通用池实现。对需要合并的每种类型的对象使用不同的池:

private static Stack<T1> poolT1 = new Stack<T1>(); 
...
T1 myobject = poolT1.Pop(); 

我个人建议更喜欢Stack over Queue,因为它会返回最近使用的对象,这些对象可能会改善内存局部性 - 从而导致更好的缓存性能。

答案 1 :(得分:2)

Queue<T>对于对象池不是一个好主意,因为您经常使用密钥或其他东西访问数据。因此,ConcurrentDictionary<string, object>适用于多线程应用程序中的这种情况。你可以把它包起来让你的代码更清晰:

public class Pool
{
    private ConcurrentDictionary<string, object> m_data = new ConcurrentDictionary<string, object>();

    public T Take<T>(string key)
    {
        //fetch data from the dictionary and convert it to the type you want
    }

    //other methods like Insert...
}

答案 2 :(得分:1)

System.Collections.Queue和System.Collections.Generic.Queue之间存在差异。我想你是在引用后者。前者是弱类型的,后者是强类型的(即你必须指定类型)。

使用对象的缺点是性能,因为每次获得一个对象进行检查时你必须使用box / unbox(即你进行转换),并且你总是需要某种bi switch语句来决定这个类型对象是。您可以通过使用其他数据结构来存储有关该对象的类型信息来解决这个问题。

答案 3 :(得分:0)

您可以为要池的每种类型的对象设置一个堆栈。在你的情况下,这将是3堆栈。然后在Pool的Get方法中,您将有逻辑来确定应该使用哪个池来获取正确的对象。我通过将参数传递给Get方法来实现,但这取决于您的特定实现。

public IType Get(int type)
{
    switch (type)
    {
        case 1:
            if (pool1.Count == 0)
            {
                return new MyObject1();
            }
            else
            {
                return pool1.Pop();
            }
            break;
        case 2:
            if (pool2.Count == 0)
            {
                return new MyObject2();
            }
            else
            {
                return pool2.Pop();
            }
            break;
        case 3:
            if (pool3.Count == 0)
            {
                return new MyObject3();
            }
            else
            {
                return pool3.Pop();
            }
            break;
     }
}

在你的免费方法中,你可以有一个If ... Else这样:

public void Free(IType obj)
{
    if (obj is MyObject1)
    {
        if (pool1.Count < MAX_POOL_SIZE)
            pool1.Push(obj);
    }
    else if (obj is MyObject2)
    {
        if (pool2.Count < MAX_POOL_SIZE)
            pool2.Push(obj);
    }
    else if (obj is MyObject2)
    {
        if (pool3.Count < MAX_POOL_SIZE)
            pool3.Push(obj);
    }
}

理想情况下,您可以控制要池化的对象的类。在这种情况下,您将为它们添加一个明确指定其真实类型的属性,然后在Free方法中,您将在该属性上执行逻辑,而不必使用反射。这会给你更好的表现。