简单封装个对象池
看到公司使用 ObjectPool
对象池缓存rabbitmq连接
看了下具体实现,感觉用起来太繁琐
需要实现 IPooledObjectPolicy
接口, 自定义一个 Policy
而这个接口中最主要的可能就是 Create
方法, 即在池中无对象的情况下如何创建新的
所以我觉得可以尝试封装一下,简化使用
第一版
首先定义一个泛型 Policy
MyPoolPolicy
public class MyPoolPolicy<T> : IPooledObjectPolicy<T>
{
public static Func<T> CreateFunc = null;
public static Func<T, bool> ReturnFunc = null;
public T Create()
{
if (CreateFunc == null)
return default;
return CreateFunc();
}
public bool Return(T obj)
{
return ReturnFunc(obj);
}
}
定义两个静态的委托, 修改委托即可改变 Create
中的实现
然后简单写一个静态工具方法用于创建对象池
public class PoolTool
{
public static ObjectPool<T> CreatePool<T>(Func<T> create, Func<T, bool> returnFunc = null) where T : class
{
MyPoolPolicy<T>.CreateFunc = create;
returnFunc ??= item => true;
MyPoolPolicy<T>.ReturnFunc = returnFunc;
return new DefaultObjectPool<T>(new MyPoolPolicy<T>());
}
}
一般来说 Return
不是太重要,可以给个默认的实现
使用的时候就比较简单了
var pool = PoolTool.CreatePool(() => {
// 一些自定义的东西
return new MyClass {
...
}
});
这样就可以获取到一个可用的对象池, 调用 pool.Get()
就可以生成一个 MyClass
对象
第二版
上一版存在一个问题, 由于只有一个静态的委托对象, 所以当我再次调用 PoolTool.CreatePool<MyClass>()
传入新委托时, 之前创建的 pool 实现会被修改为传入的新的委托, 这可能会产生一些问题, 虽然在一般情况下一种类型只会有一种实现, 但是封装的时候也必须要考虑的到这种情况
public class MyPoolPolicy<T> : IPooledObjectPolicy<T>
{
/// <summary>
/// 每个pool实例的index标记,用于从集合中取出对应的委托
/// </summary>
public int? Index { get; set; }
public static Func<int, T> CreateFunc = null;
public static Func<int, T, bool> ReturnFunc = null;
public static List<Func<T>> CreateFuncs = new();
public static List<Func<T, bool>> ReturnFuncs = new();
public MyPoolObjectPolicy() { }
public MyPoolObjectPolicy(int index)
{
Index = index;
}
public T Create()
{
return CreateFunc(Index.Value);
}
public bool Return(T obj)
{
return ReturnFunc(Index.Value, obj);
}
}
public class PoolTool
{
public static ObjectPool<T> CreatePool<T>(Func<T> create, Func<T, bool> returnFunc = null) where T : class
{
MyPoolPolicy<T>.CreateFuncs.Add(create);
returnFunc ??= item => true;
MyPoolPolicy<T>.ReturnFuncs.Add(returnFunc);
var policy = new MyPoolPolicy<T>(MyPoolPolicy<T>.CreateFuncs.Count - 1);
MyPoolPolicy<T>.CreateFunc = (index) => MyPoolPolicy<T>.CreateFuncs[index]();
MyPoolPolicy<T>.ReturnFunc = (index, item) => MyPoolPolicy<T>.ReturnFuncs[index](item);
return new DefaultObjectPool<T>(policy);
}
}
每次传入的委托会放到 CreateFuncs,ReturnFuncs
集合中,
并且每个新建的pool实例都会有一个用于标记的 Index
两者配合即可让同一个 MyPoolPolicy
拥有多个实现
警告
本文只是提供一个简单的思路, 更加复杂的问题需要结合实际情况考虑再做修改