Есть ли общий пул объектов для .NET?
У меня есть класс, который стоит строить с точки зрения времени и памяти. Я хотел бы поддерживать пул этих вещей и распределять их по требованию нескольким потокам в том же процессе.
Есть ли общий пул объектов, который уже проверен и проверен? (Я не хочу, чтобы объединение COM +.)
Ответы
Ответ 1
Нет Cheeso, общий пул объектов не существует. Но это хорошая идея. Я думаю, что это будет довольно просто развиваться. Главное, что он хорошо работает в многопоточной среде.
Я думаю, что это интересная проблема дизайна. Например, если это необходимо для масштабирования на оборудовании класса sever - и - вы часто ставите объекты в отдельные темы, тогда вы можете это сделать:
- Сохраняйте единый центральный пул объектов.
- Сохранять пул потоков (кеш), который заполняется, когда он вызван в первый раз для потока, и когда он становится пустым.
Таким образом, вы избегаете конфликтов в каждом потоке для большинства запросов.
Различные условия эксплуатации приведут вас к другому дизайну. Например, если распределение объектов редки или число потоков невелико, тогда проще было бы просто заблокировать коллекцию. Это не будет хорошо масштабироваться, но в этом случае это необходимо.
Если вы правильно разработали класс или интерфейс, то вы можете изменить реализацию с течением времени для обработки более сложных сценариев.
Ответ 2
Выталкивается прямо из MSDN, здесь приведен пример использования одного из новых типов одновременного сбора в .NET 4:
В следующем примере показано, как реализовать пул объектов с System.Collections.Concurrent.ConcurrentBag<T>
в качестве хранилища.
public class ObjectPool<T>
{
private ConcurrentBag<T> _objects;
private Func<T> _objectGenerator;
public ObjectPool(Func<T> objectGenerator)
{
if (objectGenerator == null)
throw new ArgumentNullException("objectGenerator");
_objects = new ConcurrentBag<T>();
_objectGenerator = objectGenerator;
}
public T GetObject()
{
T item;
if (_objects.TryTake(out item))
return item;
return _objectGenerator();
}
public void PutObject(T item)
{
_objects.Add(item);
}
}
Ответ 3
Класс ObjectPool, предложенный 280Z28, выглядит довольно неплохо. Вы также можете подумать о создании другого класса, который реализует IDisposable и обертывает возвращаемое значение GetObject(). Это гарантирует, что объекты возвращаются в ваш пул и читаются красиво:
class ObjectPoolReference<T> : IDisposable
{
public ObjectPool<T> Pool { get; private set; }
public T Instance { get; private set; }
public ObjectPoolReference(ObjectPool<T> pool, T instance)
{
Pool = pool;
Instance = instance;
}
~ObjectPoolReference()
{
Dispose();
}
#region IDisposable Members
private bool _Disposed = false;
public void Dispose()
{
if (!_Disposed)
{
Pool.PutObject(Instance);
_Disposed = true;
}
}
#endregion
}
//instance of the pool
ObjectPool<Foo> Pool;
//"using" ensures the reference is disposed at the end of the block, releasing the object back to the pool
using (var Ref = Pool.GetObject())
{
Ref.Instance.DoSomething();
}
Ответ 4
Почему бы просто написать синглтон, который просто служит шлюзом для массива объектов, которые были созданы.
Когда объект передается, затем удаляйте его из доступного списка, помещайте его в выпадающий список, а затем, когда он возвращается, отмените это.
Используя один сингл для этого, у вас есть статический класс для вызова всего, и если дорогой класс является внутренним классом singleton, то ничто другое не может создать дорогой класс, и вы можете контролировать, сколько объектов создавать, легко.
Ответ 5
Просто чтобы поделиться. Я создал общую библиотеку общих пулов .net, используя общий пул Apache в качестве модели. http://cobrary.wordpress.com/net-common-pool-library/