Как извлечь разные объекты из пула? - PullRequest
0 голосов
/ 08 февраля 2012

Мне нужно хранить три разных типа объектов в пуле объектов, и их нужно извлекать в зависимости от потребности.

Я пытался реализовать его с помощью очереди, но я смог сделать это только с одним типом.

Можно ли сохранять и извлекать различные типы объектов в пуле объектов? Как?

Ответы [ 4 ]

2 голосов
/ 08 февраля 2012

Рассмотрите возможность использования реализации общего пула. Используйте отдельный пул для каждого типа объекта, который необходимо объединить:

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

Я бы лично предложил предпочесть Stack, а не Queue, поскольку он возвращает недавно использованные объекты, что потенциально улучшает локальность памяти и, следовательно, приводит к повышению производительности кэша.

2 голосов
/ 08 февраля 2012

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...
}
1 голос
/ 08 февраля 2012

Существует разница между System.Collections.Queue и System.Collections.Generic.Queue.Я думаю, что вы ссылаетесь на последнее.Первый типизирован слабо, последний типизирован строго (т.е. вы должны указать тип).

Недостатком использования объектов является производительность, потому что вы должны ставить / снимать коробку каждый раз, когда вы получаете объект для проверки (т.е. вы бросаете его), и вам всегда нужно иметь какой-то оператор bi switch для принятия решения.какой тип этот объект.Вы можете обойти это, используя дополнительные структуры данных для хранения типизированной информации об объекте.

0 голосов
/ 12 декабря 2012

У вас может быть стек для каждого типа объектов, которые вы хотите объединить.В вашем случае это будет 3 стека.Тогда внутри метода 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;
     }
}

В вашем методе Free вы можете использовать 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 вы бы применили логику к этому свойству вместо использования отражения.Это даст вам лучшую производительность.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...