예제 #1
0
        /// <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);
        }
예제 #2
0
        /// <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);
        }