public async Task DoConsumeAsync(CancellationToken cancellationToken)
        {
            //Iterate while thread hasn't been canceled
            while (!cancellationToken.IsCancellationRequested)
            {
                //Create BasicDeliverEventArgs object and start trying to get the next message on the queue
                BasicDeliverEventArgs lastResult;
                var messageReceived = _subscription.Next(Convert.ToInt32(CheckAliveFrequency.TotalMilliseconds),
                                                         out lastResult);

                //If a message hasn't been succesfully fetched from the queue
                if (!messageReceived)
                {
                    //If the model has been closed
                    if (!_model.IsOpen)
                    {
                        //Dispose ConsumerWorker
                        Dispose();

                        //Throw AlreadyClosedException (model is already closed)
                        throw new global::RabbitMQ.Client.Exceptions.AlreadyClosedException(_model.CloseReason);
                    }
                }

                //If something was in fact returned from the queue
                if (lastResult != null)
                {
                    //Get message body
                    var messageBody = GetBody(lastResult);

                    //Create empty messageObject instance
                    var messageObject = default(T);

                    try
                    {
                        //Try to deserialize message body into messageObject
                        messageObject = _serializer.Deserialize <T>(messageBody);
                    }
                    catch (Exception exception)
                    {
                        //Create DeserializationException to pass to RejectionHandler
                        var deserializationException = new DeserializationException("Unable to deserialize data.", exception)
                        {
                            SerializedDataString = messageBody,
                            SerializedDataBinary = lastResult.Body,
                            QueueName            = _subscription.QueueName
                        };
                        //Pass DeserializationException to RejectionHandler
                        _messageRejectionHandler.OnRejection(deserializationException);

                        //Remove message from queue after RejectionHandler dealt with it
                        Nack(lastResult.DeliveryTag, false);
                    }

                    //If message has been successfully deserialized and messageObject is populated
                    if (messageObject != null)
                    {
                        //Create messageFeedbackSender instance with corresponding model and deliveryTag
                        IMessageFeedbackSender messageFeedbackSender = new RabbitMQMessageFeedbackSender(_model, lastResult.DeliveryTag);

                        try
                        {
                            //Call given messageProcessingWorker's OnMessage method to proceed with message processing
                            await _messageProcessingWorker.OnMessageAsync(messageObject, messageFeedbackSender,
                                                                          cancellationToken).ConfigureAwait(false);

                            //If message has been processed with no errors but no Acknoledgement has been given
                            if (!messageFeedbackSender.MessageAcknoledged)
                            {
                                //Acknoledge message
                                _subscription.Ack();
                            }
                        }
                        catch (Exception)
                        {
                            //If something went wrong with message processing and message hasn't been acknoledged yet
                            if (!messageFeedbackSender.MessageAcknoledged)
                            {
                                //Negatively Acknoledge message, asking for requeue
                                Nack(lastResult.DeliveryTag, true);
                            }

                            //Rethrow catched Exception
                            throw;
                        }
                    }
                }

                //In the end of the consumption loop, check if scaleDown has been requested
                if (_scaleCallbackFunc())
                {
                    //If so, break consumption loop to let the thread end gracefully
                    break;
                }
            }

            //Loop ended, dispose ConsumerWorker
            Dispose();
        }
        public async Task DoConsumeAsync(CancellationToken cancellationToken)
        {
            _modelConsumer.BasicQos(0, _prefetchCount, false);

            using (var subscription = new RabbitMQSubscription(_modelConsumer, _queueName, false))
            {
                //Iterate while thread hasn't been canceled
                while (!cancellationToken.IsCancellationRequested)
                {
                    //Create BasicDeliverEventArgs object and start trying to get the next message on the queue
                    var messageReceived = subscription.Next(Convert.ToInt32(CheckAliveFrequency.TotalMilliseconds),
                                                            out var lastResult);

                    if (messageReceived)
                    {
                        if (lastResult != null)
                        {
                            //Get message body
                            var messageBody = GetBody(lastResult);

                            try
                            {
                                //Try to deserialize message body into messageObject
                                var messageObject = _serializer.Deserialize <T>(messageBody);

                                //Create messageFeedbackSender instance with corresponding model and deliveryTag
                                IFeedbackSender feedbackSender = new RabbitMQMessageFeedbackSender(subscription, lastResult);

                                try
                                {
                                    //Call given messageProcessingWorker's OnMessage method to proceed with message processing
                                    var context = new RabbitMQConsumerContext(_queueClient, _modelPublisher);
                                    await _messageProcessingWorker.OnMessageAsync(messageObject, context, feedbackSender,
                                                                                  cancellationToken).ConfigureAwait(false);

                                    //If message has been processed with no errors but no Acknoledgement has been given
                                    if (!feedbackSender.HasAcknoledged)
                                    {
                                        //Acknoledge message
                                        feedbackSender.Ack();
                                    }
                                }
                                catch (Exception e)
                                {
                                    //If something went wrong with message processing and message hasn't been acknoledged yet
                                    if (!feedbackSender.HasAcknoledged)
                                    {
                                        //Negatively Acknoledge message, asking for requeue
                                        feedbackSender.Nack(true);
                                    }

                                    //Rethrow caught Exception
                                    throw;
                                }
                            }
                            catch (Exception exception)
                            {
                                //Create DeserializationException to pass to RejectionHandler
                                var deserializationException = new DeserializationException("Unable to deserialize data.", exception)
                                {
                                    SerializedDataString = messageBody,
                                    SerializedDataBinary = lastResult.Body,
                                    QueueName            = subscription.QueueName
                                };
                                //Pass DeserializationException to RejectionHandler
                                await _messageRejectionHandler.OnRejectionAsync(deserializationException).ConfigureAwait(false);

                                //Remove message from queue after RejectionHandler dealt with it
                                subscription.Nack(lastResult, false, false);
                            }
                        }
                    }
                    else
                    {
                        if (subscription.Model.IsClosed)
                        {
                            throw new Exception(
                                      $"Model is already closed for RabbitMQConsumerWorker. Queue: {_queueName}");
                        }
                    }

                    subscription.Nack(true);
                }
            }
        }