使用ConcurrentBag的对象池实现:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
/// <summary>
/// 使用ConcurrentBag的对象池实现
/// </summary>
/// <typeparam name="T"></typeparam>
public class ObjectPool<T>
{
        private ConcurrentBag<T> _objects;
        private Func<T> _objectGenerator;

        public ObjectPool(Func<T> objectGenerator)
        {
            if (objectGenerator == null) throw new ArgumentNullException("need a 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);
        }
}

Usage

1
2
3
4
5
6
7
8
ObjectPool<FaceRecognition> frpool;

frpool = new ObjectPool<FaceRecognition>(() => FaceRecognition.Create("models"));

var fr = frpool.GetObject();
//尽情的使用 fr
var encodings = fr.FaceEncodings(image);
frpool.PutObject(fr);

限制对象池的最大实例数量以及释放所有实例

可以再进一步,控制对象池中的最大对象数量,如下实现:

  • 使用一个计数器和一个锁,控制对象的产生;
  • 当池内对象数量达到限制时,就不再创建新对象而是轮询等;
  • 当有可用实例重新返回到对象池的时候返回这个对象:
  • 支持对整个对象池进行Dispose,逐个的Dispose所有的资源
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
   /// <summary>
    /// 使用ConcurrentBag的对象池实现
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class ObjectPool<T>:IDisposable
    {
        //并发安全集合,存放可用的实例
        private ConcurrentBag<T> _objects;
        //索引所有实例,以便最终释放
        private List<T> _AllObject;
        private Func<T> _objectGenerator;
        private readonly uint _instenceLimit;
        volatile uint _instenceCount;


        object objlock = new object();

        public ObjectPool(uint instenceLimit, Func<T> objectGenerator)
        {
            _instenceLimit = instenceLimit;
            _AllObject = new List<T>();
            if (objectGenerator == null) throw new ArgumentNullException("need a objectGenerator");
            _objects = new ConcurrentBag<T>();
            _objectGenerator = objectGenerator;
        }

        public T GetObject()
        {
            T item;
            if (_objects.TryTake(out item)) return item;
            lock (objlock)
            {
                if (_instenceCount < _instenceLimit)
                {
                    _instenceCount++;
                    var ins = _objectGenerator();
                    _AllObject.Add(ins);
                    Debug.WriteLine($"创建对象,总对象数量{_instenceCount}...");
                    return ins;
                }
            }
            while (true)
            {
                if (_objects.TryTake(out item)) return item;
                Debug.WriteLine("已经达到池配额,等待对象...");
                Thread.Sleep(500);
            }
        }

        public void PutObject(T item)
        {
            _objects.Add(item);
        }

        public void Dispose()
        {
            foreach(var ins in _AllObject)
            {
                if (ins is IDisposable)
                {
                    (ins as IDisposable).Dispose();
                }
            }
        }
    }