【发布时间】:2019-01-31 16:53:33
【问题描述】:
为了能够运行在多线程环境中无法很好扩展的库,我创建了一个对象池来自动创建有限数量的实例,从而提高总吞吐量。我正在使用SemaphoreSlim 来锁定/解锁对底层实例的访问。
为了完整起见,ObjectPool<T> 派生自 here on MSDN。
/// <summary>
/// An object pool with a fixed amount of objects.
/// </summary>
/// <typeparam name="T">The type to have in this pool</typeparam>
public class FixedObjectPool<T> : ObjectPool<T>
where T : class
{
private int _maxObjectCount;
private SemaphoreSlim _objectAvailable;
public FixedObjectPool(Func<T> objectGenerator, int maxObjectCount) : base(objectGenerator)
{
_maxObjectCount = maxObjectCount;
_objectAvailable = new SemaphoreSlim(0, maxObjectCount);
}
public override T GetObject()
{
_objectAvailable.Wait(10);
return base.GetObject();
}
public override void PutObject(T item)
{
base.PutObject(item);
_objectAvailable.Release();
}
}
这个类应该每秒被调用几千次。除非指定超时时间(当前为 10 毫秒),否则对 GetObject 方法的调用似乎会死锁。
我的 2 美分是调用代码在同一个线程上运行,该线程被锁定,因此信号量没有被释放。
我如何确保在此类中通过设计,方法调用在它们自己的线程上分派,以确保信号量等待不会通过停止此方法之外的运行代码而死锁?
编辑:根据请求,当前池的使用情况如下块所示;
Parallel.For(0, 10000, (i) => {
var instance = pool.GetObject();
// Do something with said instance
pool.PutObject(instance);
});
【问题讨论】:
-
你能告诉我们一些使用池的代码吗?
-
看起来您的池最初是空的,所以您是否在尝试将它们取出之前向其中添加对象?
-
@Sean 查看更新后的问题。如果池中没有可用的实例,则会即时实例化一个新实例。
标签: c# .net multithreading