using System; using System.Collections.Concurrent; namespace System.Pool.Internal { public sealed class ObjectPool { private readonly ConcurrentBag _stack = new ConcurrentBag(); private readonly Action _actionOnGet; private readonly Action _actionOnRelease; private readonly Func _actionOnNew; public int Count { get; private set; } public ObjectPool(Action actionOnGet, Action actionOnRelease, Func actionOnNew = null) { this._actionOnGet = actionOnGet; this._actionOnRelease = actionOnRelease; this._actionOnNew = (actionOnNew ?? new Func(this.New)); } public T Get() { T t; try { ConcurrentBag stack = this._stack; do { if (stack.IsEmpty) { t = this._actionOnNew(); int count = this.Count; this.Count = count + 1; } else { if (!stack.TryTake(out t)) { t = this._actionOnNew(); int count = this.Count; this.Count = count + 1; } } } while (t == null); } catch { t = this._actionOnNew(); } Action expr_72 = this._actionOnGet; if (expr_72 != null) { expr_72(t); } return t; } public void Release(T element) { if (element == null) { return; } try { ConcurrentBag stack = this._stack; T t; if (stack.Count <= 0 || !stack.TryPeek(out t) || t.GetType() != element.GetType()) { Action expr_3A = this._actionOnRelease; if (expr_3A != null) { expr_3A(element); } stack.Add(element); } } catch { } } private T New() { return Activator.CreateInstance(); } } }