private static void DestroyModel(AmqpModelContainer modelContainer)
        {
            if (modelContainer != null && modelContainer.Channel != null)
            {
                try
                {
                    modelContainer.Destroy();
                }
                catch { }

                try
                {
                    modelContainer.Channel.Dispose();
                }
                catch { }
            }
        }
        internal AmqpModelContainer GetModel(ChannelFlags flags)
        {
            if (flags == ChannelFlags.Consumer)
            {
                //Do not pool consumer related channels
                return(CreateModel(flags));
            }

            //Search pool for a model:
            AmqpModelContainer model = null;

            //First get the queue
            ConcurrentQueue <AmqpModelContainer> queue = _pool[(int)flags];

            bool retry;
            int  tick = Environment.TickCount;

            //Dequeue queue until an unexpired model is found
            do
            {
                retry = false;
                model = null;
                if (queue.TryDequeue(out model))
                {
                    if (HasModelExpired(tick, model))
                    {
                        DestroyModel(model); // dispose model for good
                        retry = true;
                    }
                }
            }while (retry);

            if (model == null)
            {
                //Wasn't found, so create a new one
                model = CreateModel(flags);
            }

            return(model);
        }
        internal void ReturnModel(AmqpModelContainer modelContainer)
        {
            //Do not return channel to pool if either:
            //1. Pooler is disposed
            //2. Channel is consumer related
            //3. Channel has expired
            if (_disposed || modelContainer.Discard || HasModelExpired(Environment.TickCount, modelContainer))
            {
                DestroyModel(modelContainer);
                return;
            }

            //Insert model in pool
            ConcurrentQueue <AmqpModelContainer> queue = _pool[(int)modelContainer.Flags];

            queue.Enqueue(modelContainer);

            //It's possible for the disposed flag to be set (and the pool flushed) right after the first _disposed check
            //but before the modelContainer was added, so check again.
            if (_disposed)
            {
                Flush();
            }
        }
 private static bool HasModelExpired(int currentTickCount, AmqpModelContainer modelContainer)
 {
     //TickCount wrapped around (so timespan can't be trusted) or model has expired
     return(currentTickCount < modelContainer.Created || modelContainer.Created < (currentTickCount - MODEL_EXPIRY_TIMESPAN));
 }