public bool NonReceiveContextPoisonHandling(MsmqMessageProperty messageProperty)
        {
            if (messageProperty.AbortCount <= this.ReceiveParameters.ReceiveRetryCount)
            {
                return(false);
            }
            int retryCycle = messageProperty.MoveCount / 2;

            lock (this)
            {
                if (this.disposed)
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ObjectDisposedException(this.GetType().ToString()));
                }

                if (retryCycle >= this.ReceiveParameters.MaxRetryCycles)
                {
                    if (TD.MaxRetryCyclesExceededMsmqIsEnabled())
                    {
                        TD.MaxRetryCyclesExceededMsmq(messageProperty.MessageId);
                    }
                    FinalDisposition(messageProperty);
                }
                else
                {
                    MsmqReceiveHelper.MoveReceivedMessage(this.mainQueue, this.retryQueueForMove, messageProperty.LookupId);
                    MsmqDiagnostics.PoisonMessageMoved(messageProperty.MessageId, false, this.receiver.InstanceId);
                }
            }
            return(true);
        }
        public bool ReceiveContextPoisonHandling(MsmqMessageProperty messageProperty)
        {
            // The basic idea is to use the message move count to get the number of retry attempts the message has been through
            // The computation of the retry count and retry cycle count is slightly involved due to fact that the message being processed
            // could have been recycled message. (Recycled message is the message that moves from lock queue to retry queue to main queue
            // and back to lock queue
            //

            // Count to tally message recycling (lock queue to retry queue to main queue adds move count of 2 to the message)
            const int retryMoveCount = 2;

            // Actual number of times message is received before recycling to retry queue
            int actualReceiveRetryCount = this.ReceiveParameters.ReceiveRetryCount + 1;

            // The message is recycled these many number of times
            int maxRetryCycles = this.ReceiveParameters.MaxRetryCycles;

            // Max change in message move count between recycling
            int maxMovePerCycle = (2 * actualReceiveRetryCount) + 1;

            // Number of recycles the message has been through
            int messageCyclesCompleted = messageProperty.MoveCount / (maxMovePerCycle + retryMoveCount);

            // Total number of moves on the message at the end of the last recycle
            int messageMoveCountForCyclesCompleted = messageCyclesCompleted * (maxMovePerCycle + retryMoveCount);

            // The differential move count for the current cycle
            int messageMoveCountForCurrentCycle = messageProperty.MoveCount - messageMoveCountForCyclesCompleted;

            lock (this)
            {
                if (this.disposed)
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ObjectDisposedException(this.GetType().ToString()));
                }

                // Check if the message has already completed its max recycle count (MaxRetryCycles)
                // and the disposed the message first. Such a message was previously disposed using the ReceiveErrorHandling method
                // and the channel/listener would immediately fault
                //
                if (messageCyclesCompleted > maxRetryCycles)
                {
                    FinalDisposition(messageProperty);
                    return(true);
                }

                // Check if the message is eligible for recycling/disposition
                if (messageMoveCountForCurrentCycle >= maxMovePerCycle)
                {
                    if (TD.ReceiveRetryCountReachedIsEnabled())
                    {
                        TD.ReceiveRetryCountReached(messageProperty.MessageId);
                    }
                    if (messageCyclesCompleted < maxRetryCycles)
                    {
                        // The message is eligible for recycling, move the message the message to retry queue
                        MsmqReceiveHelper.MoveReceivedMessage(this.lockQueueForReceive, this.retryQueueForMove, messageProperty.LookupId);
                        MsmqDiagnostics.PoisonMessageMoved(messageProperty.MessageId, false, this.receiver.InstanceId);
                    }
                    else
                    {
                        if (TD.MaxRetryCyclesExceededMsmqIsEnabled())
                        {
                            TD.MaxRetryCyclesExceededMsmq(messageProperty.MessageId);
                        }
                        // Dispose the message using ReceiveErrorHandling
                        FinalDisposition(messageProperty);
                    }

                    return(true);
                }
                else
                {
                    return(false);
                }
            }
        }