Могу ли я заглянуть в пустой MSMQ без исключения?

Насколько я вижу из документации, вы должны проверять, есть ли сообщения в очереди сообщений, используя метод 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 на С#, но если мне нужно будет выйти из-под контроля, чтобы решить эту проблему, это может быть вариантом. И обратите внимание, что я хочу решение без использования WCF с MSMQ.


person Torbjørn    schedule 17.09.2009    source источник


Ответы (4)


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

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

  • Я думаю, что в контексте межпроцессного взаимодействия (что и делает msmq) стоимость исключения не важна. Тестируйте, если хотите быть уверенным.
  • Я так не думаю.
person Igal Serban    schedule 17.09.2009
comment
Мы передаем сообщения через конвейер сервисов, где мы используем очереди между ними. Мы хотим иметь максимально возможную пропускную способность, так что это не маловажно, но пока у нас достаточно хорошая производительность. - person Torbjørn; 18.09.2009
comment
Я подожду, чтобы увидеть, получу ли я какие-либо другие комментарии, но если нет, я приму ваш ответ: | - person Torbjørn; 19.09.2009

  • Да, вы правы в предположении, что исключения обходятся дорого. На самом деле дорого бросить, а не поймать. Время от времени очередь может быть пустой, и нормальное состояние не должно приводить к возникновению исключения.

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

Пример:

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

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

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

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

person Oskar Sjöberg    schedule 20.05.2011

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

person blah    schedule 10.12.2009

как насчет того, чтобы попробовать mq.GetAllMessages().Length> 0

person Phani    schedule 05.10.2010
comment
Действительно? Даже если ваша очередь может содержать 1000 или 10 000 больших сообщений? Это все равно, что съесть весь супермаркет пустым только потому, что вы хотите знать, остались ли у них яблоки. - person oɔɯǝɹ; 25.08.2012