/// <summary>
        ///     Adds an object to the end of the queue.
        /// </summary>
        /// <param name="item">the object to add to the queue</param>
        public void Enqueue(T item)
        {
            SingleLinkNode <T> oldTail = null;

            var newNode = new SingleLinkNode <T> {
                Item = item
            };

            var newNodeWasAdded = false;

            while (!newNodeWasAdded)
            {
                oldTail = _tail;
                var oldTailNext = oldTail.Next;

                if (_tail == oldTail)
                {
                    if (oldTailNext == null)
                    {
                        newNodeWasAdded =
                            Interlocked.CompareExchange(ref _tail.Next, newNode, null) == null;
                    }
                    else
                    {
                        Interlocked.CompareExchange(ref _tail, oldTailNext, oldTail);
                    }
                }
            }

            Interlocked.CompareExchange(ref _tail, newNode, oldTail);
            Interlocked.Increment(ref _count);
        }
        /// <summary>
        ///     Clears the queue.
        /// </summary>
        /// <remarks>This method is not thread-safe.</remarks>
        public void Clear()
        {
            var currentNode = _head;

            while (currentNode != null)
            {
                var tempNode = currentNode;
                currentNode = currentNode.Next;

                tempNode.Item = default(T);
                tempNode.Next = null;
            }

            _head  = new SingleLinkNode <T>();
            _tail  = _head;
            _count = 0;
        }
        /// <summary>
        ///     Removes and returns the object at the beginning of the queue.
        /// </summary>
        /// <param name="item">
        ///     when the method returns, contains the object removed from the beginning of the queue,
        ///     if the queue is not empty; otherwise it is the default value for the element type
        /// </param>
        /// <returns>
        ///     true if an object from removed from the beginning of the queue;
        ///     false if the queue is empty
        /// </returns>
        public bool TryDequeue(out T item)
        {
            item = default(T);
            SingleLinkNode <T> oldHead = null;

            var haveAdvancedHead = false;

            while (!haveAdvancedHead)
            {
                oldHead = _head;
                var oldTail     = _tail;
                var oldHeadNext = oldHead.Next;

                if (oldHead == _head)
                {
                    if (oldHead == oldTail)
                    {
                        if (oldHeadNext == null)
                        {
                            return(false);
                        }

                        Interlocked.CompareExchange(ref _tail, oldHeadNext, oldTail);
                    }

                    else
                    {
                        item             = oldHeadNext.Item;
                        haveAdvancedHead =
                            Interlocked.CompareExchange(ref _head, oldHeadNext, oldHead) == oldHead;
                    }
                }
            }

            Interlocked.Decrement(ref _count);
            return(true);
        }
 /// <summary>
 ///     Default constructor.
 /// </summary>
 public LockFreeQueue()
 {
     _head = new SingleLinkNode <T>();
     _tail = _head;
 }