private void ReceiveMessage(object context)
        {
            int sleepTime = 1;
            while (shouldContinue)
            {
                Thread.Sleep(sleepTime);
                try
                {
                    using (var tx = _sqlQueueManager.BeginTransaction())
                    {
                        if (!_sqlQueueManager.Peek(_queueId))
                        {
                            sleepTime += 100;
                            sleepTime = Math.Min(sleepTime, SleepMax);
                            continue;
                        }
                        sleepTime = 1;
                        tx.Transaction.Commit();
                    }
                }
                catch (TimeoutException)
                {
                    logger.DebugFormat("Could not find a message on {0} during the timeout period",
                                       queueEndpoint);
                    continue;
                }
                    catch(SqlException e)
                {
                    logger.Debug("Could not get message from database.", e);
                    continue;
                }
                catch (ObjectDisposedException)
                {
                    logger.DebugFormat("Shutting down the transport for {0} thread {1}", queueEndpoint, context);
                    return;
                }
                catch (InvalidOperationException e)
                {
                    logger.Error(
                        "An error occured while recieving a message, shutting down message processing thread", e);
                    return;
                }

                if (shouldContinue == false)
                    return;

                Message message;
                try
                {
                    using (var tx = _sqlQueueManager.BeginTransaction())
                    {
                        message = _sqlQueueManager.Receive(_queueId, TimeSpan.FromSeconds(10));
                        tx.Transaction.Commit();
                    }
                }
                catch (TimeoutException)
                {
                    logger.DebugFormat("Could not find a message on {0} during the timeout period",
                                       queueEndpoint);
                    continue;
                }
                catch (SqlException e)
                {
                    logger.Debug("Could not get message from database.",
                                       e);
                    continue;
                }
                catch (Exception e)
                {
                    logger.Error(
                        "An error occured while recieving a message, shutting down message processing thread",
                        e);
                    return;
                }

                if (message.ProcessedCount > numberOfRetries)
                {
                    using (var tx = _sqlQueueManager.BeginTransaction())
                    {
                        Queue.MoveTo(SubQueue.Errors.ToString(), message);
                        Queue.EnqueueDirectlyTo(SubQueue.Errors.ToString(), new MessagePayload
                                                                                {
                                                                                    SentAt = DateTime.Now,
                                                                                    Data = null,
                                                                                    Headers = new NameValueCollection
                                                                                                  {
                                                                                                      {
                                                                                                          "correlation-id", message.Id.ToString()
                                                                                                      },
                                                                                                      {
                                                                                                          "retries", message.ProcessedCount.ToString(CultureInfo.InvariantCulture)
                                                                                                      }
                                                                                                  }
                                                                                });
                        tx.Transaction.Commit();
                    }
                    continue;
                }

                var messageWithTimer = new MessageWithTimer {Message = message};
                var messageProcessingTimer = new Timer(extendMessageLeaaseIfMessageStillInProgress, messageWithTimer,
                                                       TimeSpan.FromSeconds(40), TimeSpan.FromMilliseconds(-1));
                messageWithTimer.Timer = messageProcessingTimer;

                try
                {
                    var msgType = (MessageType) Enum.Parse(typeof (MessageType), message.Headers["type"]);
                    logger.DebugFormat("Starting to handle message {0} of type {1} on {2}",
                                       message.Id,
                                       msgType,
                                       queueEndpoint);
                    switch (msgType)
                    {
                        case MessageType.AdministrativeMessageMarker:
                            ProcessMessage(message,
                                           AdministrativeMessageArrived,
                                           AdministrativeMessageProcessingCompleted,
                                           null,
                                           null);
                            break;
                        case MessageType.ShutDownMessageMarker:
                            //ignoring this one
                            using(var tx = _sqlQueueManager.BeginTransaction())
                            {
                                _sqlQueueManager.MarkMessageAsReady(message);
                                tx.Transaction.Commit();
                            }
                            break;
                        case MessageType.TimeoutMessageMarker:
                            var timeToSend = XmlConvert.ToDateTime(message.Headers["time-to-send"],
                                                                   XmlDateTimeSerializationMode.Unspecified);
                            if (timeToSend > DateTime.Now)
                            {
                                timeout.Register(message);
                                using (var tx = queue.BeginTransaction())
                                {
                                    queue.MoveTo(SubQueue.Timeout.ToString(), message);
                                    tx.Transaction.Commit();
                                }
                            }
                            else
                            {
                                ProcessMessage(message,
                                               MessageArrived,
                                               MessageProcessingCompleted,
                                               BeforeMessageTransactionCommit,
                                               BeforeMessageTransactionRollback);
                            }
                            break;
                        default:
                            ProcessMessage(message,
                                           MessageArrived,
                                           MessageProcessingCompleted,
                                           BeforeMessageTransactionCommit,
                                           BeforeMessageTransactionRollback);
                            break;
                    }
                }
                catch (Exception exception)
                {
                    logger.Debug("Could not process message", exception);
                }
                message.FinishedProcessing = true;
            }
        }
        private void ReceiveMessage(object context)
        {
            int sleepTime = 1;

            while (shouldContinue)
            {
                Thread.Sleep(sleepTime);
                try
                {
                    using (var tx = _sqlQueueManager.BeginTransaction())
                    {
                        if (!_sqlQueueManager.Peek(_queueId))
                        {
                            sleepTime += 100;
                            sleepTime  = Math.Min(sleepTime, SleepMax);
                            continue;
                        }
                        sleepTime = 1;
                        tx.Transaction.Commit();
                    }
                }
                catch (TimeoutException)
                {
                    logger.DebugFormat("Could not find a message on {0} during the timeout period.",
                                       queueEndpoint);
                    continue;
                }
                catch (SqlException e)
                {
                    logger.Warn("Could not get message from database.", e);
                    continue;
                }
                catch (ObjectDisposedException)
                {
                    logger.DebugFormat("Shutting down the transport for {0} thread {1}.", queueEndpoint, context);
                    return;
                }
                catch (InvalidOperationException e)
                {
                    logger.Error(
                        "An error occured while recieving a message, clearing connection pool and make a new attempt after some sleep.", e);

                    SqlConnection.ClearAllPools();
                    sleepTime = SleepMax;
                    continue;
                }
                catch (Exception e)
                {
                    logger.Error(
                        "An error occured while recieving a message, shutting down message processing thread",
                        e);
                    return;
                }

                if (shouldContinue == false)
                {
                    return;
                }

                Message message;
                try
                {
                    using (var tx = _sqlQueueManager.BeginTransaction())
                    {
                        message = _sqlQueueManager.Receive(_queueId, TimeSpan.FromSeconds(10));
                        tx.Transaction.Commit();
                    }
                }
                catch (TimeoutException)
                {
                    logger.DebugFormat("Could not find a message on {0} during the timeout period",
                                       queueEndpoint);
                    continue;
                }
                catch (SqlException e)
                {
                    logger.Debug("Could not get message from database.",
                                 e);
                    continue;
                }
                catch (InvalidOperationException e)
                {
                    logger.Error(
                        "An error occured while recieving a message, clearing connection pool and make a new attempt after some sleep.", e);

                    SqlConnection.ClearAllPools();
                    sleepTime = SleepMax;
                    continue;
                }
                catch (Exception e)
                {
                    logger.Error(
                        "An error occured while recieving a message, shutting down message processing thread",
                        e);
                    return;
                }

                if (message.ProcessedCount > numberOfRetries)
                {
                    using (var tx = _sqlQueueManager.BeginTransaction())
                    {
                        Queue.MoveTo(SubQueue.Errors.ToString(), message);
                        Queue.EnqueueDirectlyTo(SubQueue.Errors.ToString(), new MessagePayload
                        {
                            SentAt  = DateTime.UtcNow,
                            Data    = null,
                            Headers = new NameValueCollection
                            {
                                {
                                    "correlation-id", message.Id.ToString()
                                },
                                {
                                    "retries", message.ProcessedCount.ToString(CultureInfo.InvariantCulture)
                                }
                            }
                        });
                        tx.Transaction.Commit();
                    }
                    continue;
                }

                var messageWithTimer = new MessageWithTimer {
                    Message = message
                };
                var messageProcessingTimer = new Timer(extendMessageLeaaseIfMessageStillInProgress, messageWithTimer,
                                                       TimeSpan.FromSeconds(40), TimeSpan.FromMilliseconds(-1));
                messageWithTimer.Timer = messageProcessingTimer;

                try
                {
                    var msgType = (MessageType)Enum.Parse(typeof(MessageType), message.Headers["type"]);
                    logger.DebugFormat("Starting to handle message {0} of type {1} on {2}",
                                       message.Id,
                                       msgType,
                                       queueEndpoint);
                    switch (msgType)
                    {
                    case MessageType.AdministrativeMessageMarker:
                        ProcessMessage(message,
                                       AdministrativeMessageArrived,
                                       AdministrativeMessageProcessingCompleted,
                                       null,
                                       null);
                        break;

                    case MessageType.ShutDownMessageMarker:
                        //ignoring this one
                        using (var tx = _sqlQueueManager.BeginTransaction())
                        {
                            _sqlQueueManager.MarkMessageAsReady(message);
                            tx.Transaction.Commit();
                        }
                        break;

                    case MessageType.TimeoutMessageMarker:
                        var timeToSend = XmlConvert.ToDateTime(message.Headers["time-to-send"],
                                                               XmlDateTimeSerializationMode.Unspecified);
                        if (timeToSend > DateTime.Now)
                        {
                            timeout.Register(message);
                            using (var tx = queue.BeginTransaction())
                            {
                                queue.MoveTo(SubQueue.Timeout.ToString(), message);
                                tx.Transaction.Commit();
                            }
                        }
                        else
                        {
                            ProcessMessage(message,
                                           MessageArrived,
                                           MessageProcessingCompleted,
                                           BeforeMessageTransactionCommit,
                                           BeforeMessageTransactionRollback);
                        }
                        break;

                    default:
                        ProcessMessage(message,
                                       MessageArrived,
                                       MessageProcessingCompleted,
                                       BeforeMessageTransactionCommit,
                                       BeforeMessageTransactionRollback);
                        break;
                    }
                }
                catch (Exception exception)
                {
                    logger.Debug("Could not process message", exception);
                }
                message.FinishedProcessing = true;
            }
        }