public T GetObject()
        {
            KeyValuePair <long, T>?firstAllocator = null;

            if (Interlocked.Increment(ref checkCompleted) >= CHECK_COMPLETED_INTERVAL)
            {
                checkCompleted = 0;

                // this check is slow, so only do it occassionally
                // this may cause more objects to get created, but that is fine
                // more things will come safely off the queue when this updates
                GraphicsDevice.GetCompletedValue();
            }

            bool lockTaken = false;

            try
            {
                spinLock.Enter(ref lockTaken);

                if (liveObjects.Count > 0)
                {
                    firstAllocator = liveObjects.Peek();

                    if (firstAllocator.Value.Key < GraphicsDevice.lastCompletedFence)
                    {
                        liveObjects.Dequeue();
                    }
                    else
                    {
                        firstAllocator = null;
                    }
                }
            }
            finally
            {
                if (lockTaken)
                {
                    spinLock.Exit(true);
                }
            }

            if (firstAllocator.HasValue)
            {
                ResetObject(firstAllocator.Value.Value);
                return(firstAllocator.Value.Value);
            }

            return(CreateObject());
        }
        public T GetObject()
        {
            lock (liveObjects)
            {
                // Check if first allocator is ready for reuse
                if (liveObjects.Count > 0)
                {
                    var firstAllocator = liveObjects.Peek();
                    if (firstAllocator.Key <= GraphicsDevice.GetCompletedValue())
                    {
                        liveObjects.Dequeue();
                        ResetObject(firstAllocator.Value);
                        return(firstAllocator.Value);
                    }
                }
            }

            return(CreateObject());
        }