在时间和记忆方面,我有一个构建成本昂贵的类。我想维护这些东西的池,并在同一过程中根据需要将它们分配给多个线程。
是否有经过测试和验证的通用对象池? (我不想要COM +汇集。)
答案 0 :(得分:22)
直接从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);
}
}
答案 1 :(得分:6)
280Z28提出的ObjectPool类看起来很不错。您还可以考虑创建另一个实现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();
}
答案 2 :(得分:5)
No Cheeso,没有像这样的通用对象池。但这是个好主意。我认为开发起来非常简单。关键是让它在线程环境中运行良好。
我认为这是一个有趣的设计问题。例如,如果需要在服务器类硬件上进行扩展 - 并且 - 您将经常为单个线程提供对象,那么您可以这样做:
这样,您可以避免大多数请求的每线程争用。
不同的操作条件会导致您采用不同的设计。例如,如果对象分配很少或者线程数很少,那么只是锁定集合可能更简单。这不会很好地扩展,但在这种情况下,它需要。
如果您正确设计了类或接口,那么您可以随时更改实现以处理更复杂的方案。
答案 3 :(得分:2)
接受的答案在 2021 年不再正确。
有 Microsoft.Extensions.ObjectPool NuGet 包,它提供了对象池 DefaultObjectPool<T>
和 LeakTrackingObjectPool<T>
的两种实现
答案 4 :(得分:1)
为什么不编写一个仅用作已创建对象数组的网关的单例。
分发对象时,将其从可用列表中删除,将其放入签出列表中,然后在返回时将其反转。
通过使用单例,你有一个静态类可以调用所有东西,如果昂贵的类是单例的内部类,那么没有别的东西可以创建昂贵的类,你可以控制创建的对象数量,很容易。
答案 5 :(得分:0)
分享。我使用Apache Common pool作为模型创建了一个通用的.net公共池库。 http://cobrary.wordpress.com/net-common-pool-library/