Как проверить, является ли публичный MSMQ пустым

Есть ли способ проверить, является ли общедоступный MSMQ пустым? Для частного MSMQ это легко:

private bool IsQueueEmpty(string path)
        {
            bool isQueueEmpty = false;
            var myQueue = new MessageQueue(path);
            try
            {
                myQueue.Peek(new TimeSpan(0));
                isQueueEmpty = false;
            }
            catch (MessageQueueException e)
            {
                if (e.MessageQueueErrorCode == MessageQueueErrorCode.IOTimeout)
                {
                    isQueueEmpty = true;
                }
            }
            return isQueueEmpty;
        }

Как бы я сделал такую ​​же проверку для общедоступного MSMQ? Если я пытаюсь проверить общедоступный MSMQ с помощью приведенного выше кода, это дает мне ошибку на пике:

System.ArgumentOutOfRangeException: длина не может быть меньше нуля.

4 ответа

Решение

Peek Метод доступен только на удаленных машинах, когда вы используете имя прямого формата для доступа к очереди. Вы должны иметь возможность использовать один и тот же код, если только вы не полагаетесь на службы каталогов, чтобы доставить вас в очередь.

Прямые имена очереди обычно выглядят примерно так: DIRECT=URLAddressSpecification/QueueName

Я только начал работать с очередями сообщений, но у моего коллеги есть хороший способ проверить, пуста ли очередь:

if (MessageQueue.Exists(fullQueuePath))
{
    // FYI, GetMessageQueue() is a helper method we use to consolidate the code
    using (var messageQueue = GetMessageQueue(fullQueuePath))
    {
        var queueEnum = messageQueue.GetMessageEnumerator2();

        if (queueEnum.MoveNext())
        {
            // Queue not empty
        }
        else
        {
            // Queue empty
        }
    }
}

Преимущество использования этого метода заключается в том, что он не выдает исключение, и я не думаю, что он требует от вас ожидания истечения времени ожидания.

Чтобы проверить, пуста ли очередь, проще всего использовать метод GetAllMessages(). Если сообщений нет, очередь пуста.

       string queueName = ".\private$\testqueue";   
 if (MessageQueue.Exists(queueName))
 {   
    MessageQueue mq = new MessageQueue(queueName);
    var allMessages = mq.GetAllMessages();
    if (allMessages.Length > 0)
    {
         //Queue is not empty
    }
    else
    {
         //Queue is empty
    }
 }
 else
 {
      //Queue does not exist
 }

Лео, ты уверен в этом? Вы не можете использовать имя пути с удаленным Peek? В возвращенной ошибке не указано неверное имя формата, что было бы ожидаемо, если бы это было так. Фактически ошибка, по-видимому, находится в строке "isQueueEmpty = false" - try / catch не делает различий между строками peek и isQueueEmpty. Могу поспорить, что вызов isQueueEmpty получает исключение, которое переводится в отрицательное число. Однако теперь ваше решение может быть правильным - для многих удаленных вызовов в MSMQ требуются имена форматов, а не пути. Поэтому, если вы используете имя формата для создания myQueue, isQueueEmpty должен работать.

ура

Джон Брейквелл

Другие вопросы по тегам