/// <summary> /// Allocate an object from the pool. /// </summary> /// <remarks> /// <para> /// If there are idle instances available in the pool, the first element is activated, and /// return to the client. /// If there are no idle instances available, <see cref="IObjectFactory{T}.Make" /> is invoked to create a /// new instance. /// </para> /// <para> /// All instances are <see cref="IObjectFactory{T}.Activate" /> before being returned to the client. If the /// instances fail the activation, it will be destoryed. /// </para> /// <para> /// Exceptions throws by <see cref="IObjectFactory{T}.Activate" /> or /// <see cref="IObjectFactory{T}.Destory" /> instances are silently swallowed. /// </para> /// </remarks> /// <returns>An instance from the pool.</returns> /// <exception cref="Exception"> /// When <see cref="IObjectFactory{T}.Make" /> or /// <see cref="IObjectFactory{T}.Make" /> throws an exception. /// </exception> public override T Allocate() { var obj = _firstItem; // Try to get first item if (obj == null || obj != Interlocked.CompareExchange(ref _firstItem, null, obj)) { obj = SlowAllocate(); // Failed to get from first item, use slower method instead. } else { // Success to get from first item, try { // Activate object _factory.Activate(obj); } catch (Exception activateException) { // Failed activation // Check the exception rethrow setting CheckExceptionRethrow(activateException); try { // Destroy object _factory.Destory(obj); } catch (Exception destoryException) { // Failed to destroy // Check the exception rethrow setting CheckExceptionRethrow(destoryException); } // Failed to get from first item, use slower method instead. obj = SlowAllocate(); } } return(obj); }
/// <summary> /// Allocate an object from the pool. /// </summary> /// <remarks> /// <para> /// If there are idle instances available on the stack, the top element of the stack is popped to activate, and /// return to the client. /// If there are no idle instances available, <see cref="IObjectFactory{T}.Make" /> is invoked to create a /// new instance. /// </para> /// <para> /// All instances are <see cref="IObjectFactory{T}.Activate" /> before being returned to the client. /// </para> /// </remarks> /// <returns>An instance from the pool.</returns> /// <exception cref="Exception"> /// When <see cref="IObjectFactory{T}.Make" /> or /// <see cref="IObjectFactory{T}.Make" /> throws an exception. /// </exception> public override T Allocate() { T obj = null; while (obj == null) { // Try to get cached object from stack if (_pool.Count > 0) { obj = _pool.Pop(); try { // Activate object _factory.Activate(obj); } catch (Exception activateException) { // Failed activation // Check the exception rethrow setting CheckExceptionRethrow(activateException); try { // Destroy object _factory.Destory(obj); } catch (Exception destoryException) { // Failed to destroy // Check the exception rethrow setting CheckExceptionRethrow(destoryException); } } finally { obj = null; } } else { // Failed to get cached object, create a new one obj = _factory.Make(); if (obj == null) { throw new Exception("Factory failed to create a object."); } } } return(obj); }