Могу ли я заглянуть в пустой MSMQ без исключения? - PullRequest
6 голосов
/ 17 сентября 2009

Насколько я вижу из документации, вы должны проверить, есть ли сообщения в очереди сообщений, - использовать метод Peek. Затем вы полагаетесь на то, что он завершится с ошибкой MessageQueueException, чтобы сообщить вам, что очередь пуста.

    public bool IsQueueEmpty()
    {
        bool isQueueEmpty = false;
        MessageQueue myQueue = new MessageQueue(".\\myQueue");

        try
        {
            myQueue.Peek(new TimeSpan(0));
            isQueueEmpty = false;
        }

        catch(MessageQueueException e)
        {
            if (e.MessageQueueErrorCode == 
                MessageQueueErrorCode.IOTimeout)
            {
                isQueueEmpty = true;
            }
        }
        return isQueueEmpty;
    }

Мне всегда говорили - и я испытывал - что исключения являются дорогостоящими и не должны использоваться для нормальной работы. Итак, мои вопросы:

  • Являются ли мои предположения о том, что использование перехвата MessageQueueException является дорогостоящей корректной операцией?

  • Есть ли способ синхронно проверить наличие сообщений в очереди, не полагаясь на исключения?

Я работаю с пространством имен System.Messaging в C #, но если мне понадобится неуправляемый, чтобы решить эту проблему, это может быть вариантом. И обратите внимание, что я хочу решение без использования WCF с MSMQ.

Ответы [ 4 ]

12 голосов
/ 20 мая 2011
  • Да, вы правы в предположении, что исключения являются дорогостоящими. На самом деле это бросание, которое дорого, а не ловить. Иногда очередь может быть пустой, и нормальное состояние не должно приводить к возникновению исключения.

  • Используя MessageQueue.GetMessageEnumerator2, мы могли бы использовать перечислитель, чтобы определить, пуста очередь или нет, не загружая все сообщения. При таком подходе мы никогда не загрузим более одного сообщения.

Пример:

private static bool IsQueueEmpty(MessageQueue queue)
{
    using (var enumerator = queue.GetMessageEnumerator2())
    {
        return !enumerator.MoveNext();
    }
}

или реализовать Peek, который возвращает ноль, если очередь сообщений пуста (не проверена, но должна работать)

private static Message Peek(MessageQueue queue)
{
    using (var enumerator = queue.GetMessageEnumerator2())
    {
        return enumerator.MoveNext() ? enumerator.Current : null;
    }
}

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

1 голос
/ 17 сентября 2009

Обновление: Я не утверждаю, что производительность не важна. Но я думаю, что межпроцессное взаимодействие очень дорого по сравнению с исключением.

До обновления:

  • Я думаю, что в контексте межпроцессного взаимодействия (что делает msmq) стоимость исключения не важна Проверьте, хотите ли вы быть уверенным.
  • Я так не думаю.
0 голосов
/ 05 октября 2010

как насчет попытки mq.GetAllMessages (). Длина> 0

0 голосов
/ 10 декабря 2009

MSMQ не полностью межпроцессное взаимодействие. Межпроцессное взаимодействие в основном на одной машине, но msmq может использоваться для связи между разными компьютерами. Гарантированная доставка, с обратной стороной наличия в той же ОС.

...