就时间和内存而言,我有一个构建成本很高的课程。我想维护一个这些东西的池,并根据需要将它们分配给同一进程中的多个线程。
是否有经过测试和证明的通用对象池?(我不想要 COM+ 池。)
就时间和内存而言,我有一个构建成本很高的课程。我想维护一个这些东西的池,并根据需要将它们分配给同一进程中的多个线程。
是否有经过测试和证明的通用对象池?(我不想要 COM+ 池。)
直接从 MSDN 中提取,这里是在 .NET 4 中使用一种新的并发集合类型的示例:
下面的示例演示了如何实现一个以 a
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);
}
}
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();
}
没有 Cheeso,没有像这样的通用对象池。但这是个好主意。我认为这将是非常简单的开发。关键是让它在线程环境中运行良好。
我认为这是一个有趣的设计问题。例如,如果这需要在服务器类硬件上进行扩展——并且你会经常将对象分配给单个线程,那么你可以这样做:
这样,您可以避免大多数请求的每个线程争用。
不同的操作条件会导致您采用不同的设计。例如,如果对象分配很少或线程数很少,那么在集合周围加锁可能会更简单。这不会很好地扩展,但在这种情况下,它需要。
如果您正确设计了类或接口,那么您可以随着时间的推移更改实现以处理更复杂的场景。
接受的答案在 2021 年不再正确。
有Microsoft.Extensions.ObjectPool NuGet 包,它提供对象池的两种实现DefaultObjectPool<T>
和LeakTrackingObjectPool<T>
为什么不写一个单例来作为已创建对象数组的网关。
当一个对象被分发时,然后将它从可用列表中删除,将其放入已签出列表中,然后当它返回时,将其反转。
通过为此使用单例,您有一个静态类来调用所有内容,如果昂贵类是单例的内部类,那么没有其他东西可以创建昂贵类,并且您可以轻松控制要创建的对象数量。
只是为了分享。我使用 Apache Common pool 作为模型创建了一个通用的 .net 公共池库。 http://cobrary.wordpress.com/net-common-pool-library/