private void InternalFinalDisposition(MsmqQueue disposeFromQueue, MsmqMessageProperty messageProperty)
        {
            switch (this.ReceiveParameters.ReceiveErrorHandling)
            {
            case ReceiveErrorHandling.Drop:
                this.receiver.DropOrRejectReceivedMessage(disposeFromQueue, messageProperty, false);
                break;

            case ReceiveErrorHandling.Fault:
                MsmqReceiveHelper.TryAbortTransactionCurrent();
                if (null != this.receiver.ChannelListener)
                {
                    this.receiver.ChannelListener.FaultListener();
                }
                if (null != this.receiver.Channel)
                {
                    this.receiver.Channel.FaultChannel();
                }
                break;

            case ReceiveErrorHandling.Reject:
                this.receiver.DropOrRejectReceivedMessage(disposeFromQueue, messageProperty, true);
                MsmqDiagnostics.PoisonMessageRejected(messageProperty.MessageId, this.receiver.InstanceId);
                break;

            case ReceiveErrorHandling.Move:
                MsmqReceiveHelper.MoveReceivedMessage(disposeFromQueue, this.poisonQueue, messageProperty.LookupId);
                MsmqDiagnostics.PoisonMessageMoved(messageProperty.MessageId, true, this.receiver.InstanceId);
                break;

            default:
                Fx.Assert("System.ServiceModel.Channels.Msmq4PoisonHandler.FinalDisposition(): (unexpected ReceiveErrorHandling)");
                break;
            }
        }
        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);
        }
Exemple #3
0
        private void InternalFinalDisposition(MsmqQueue disposeFromQueue, MsmqMessageProperty messageProperty)
        {
            switch (this.ReceiveParameters.ReceiveErrorHandling)
            {
            case ReceiveErrorHandling.Fault:
                MsmqReceiveHelper.TryAbortTransactionCurrent();
                if (this.receiver.ChannelListener != null)
                {
                    this.receiver.ChannelListener.FaultListener();
                }
                if (this.receiver.Channel == null)
                {
                    break;
                }
                this.receiver.Channel.FaultChannel();
                return;

            case ReceiveErrorHandling.Drop:
                this.receiver.DropOrRejectReceivedMessage(disposeFromQueue, messageProperty, false);
                return;

            case ReceiveErrorHandling.Reject:
                this.receiver.DropOrRejectReceivedMessage(disposeFromQueue, messageProperty, true);
                MsmqDiagnostics.PoisonMessageRejected(messageProperty.MessageId, this.receiver.InstanceId);
                return;

            case ReceiveErrorHandling.Move:
                MsmqReceiveHelper.MoveReceivedMessage(disposeFromQueue, this.poisonQueue, messageProperty.LookupId);
                MsmqDiagnostics.PoisonMessageMoved(messageProperty.MessageId, true, this.receiver.InstanceId);
                break;

            default:
                return;
            }
        }
Exemple #4
0
        public bool ReceiveContextPoisonHandling(MsmqMessageProperty messageProperty)
        {
            int num            = this.ReceiveParameters.ReceiveRetryCount + 1;
            int maxRetryCycles = this.ReceiveParameters.MaxRetryCycles;
            int num3           = (2 * num) + 1;
            int num4           = messageProperty.MoveCount / (num3 + 2);
            int num5           = num4 * (num3 + 2);
            int num6           = messageProperty.MoveCount - num5;

            lock (this)
            {
                if (this.disposed)
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ObjectDisposedException(base.GetType().ToString()));
                }
                if (num4 > maxRetryCycles)
                {
                    this.FinalDisposition(messageProperty);
                    return(true);
                }
                if (num6 >= num3)
                {
                    if (num4 < maxRetryCycles)
                    {
                        MsmqReceiveHelper.MoveReceivedMessage(this.lockQueueForReceive, this.retryQueueForMove, messageProperty.LookupId);
                        MsmqDiagnostics.PoisonMessageMoved(messageProperty.MessageId, false, this.receiver.InstanceId);
                    }
                    else
                    {
                        this.FinalDisposition(messageProperty);
                    }
                    return(true);
                }
                return(false);
            }
        }
        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);
                }
            }
        }