Torbjørn
Torbjørn

Reputation: 6503

Can I peek into empty MSMQ without getting exception?

As far as I can see from the documentation, the way you are supposed to check if there are messages in a message queue is to use the Peek method. You then rely on it failing with a MessageQueueException to tell you that the queue was empty.

    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;
    }

I've always been told - and have experienced - that Exeptions are costly, and should not be used for normal operations. So my questions are:

I'm working with the System.Messaging namespace in C#, but if I would need to go unmanaged to solve this that could be an option. And note that I want a solution without using WCF with MSMQ.

Upvotes: 6

Views: 4346

Answers (4)

Oskar Sjöberg
Oskar Sjöberg

Reputation: 2878

  • Yes you are correct in the assumption that exceptions are costly. Actually it is the throwing that is expensive, not the catching. It is normal for a queue to be empty at times and a normal state should not lead to an exception being thrown.

  • By using MessageQueue.GetMessageEnumerator2 we could use the enumerator to determine if a queue is empty or not without loading all messages. With this approach we would never load more than one message.

Example:

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

or to implement Peek which returns null if the message queue is empty (untested, but should work)

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

We used code like the original to check about twenty different queues. Since we changed from the original implementation to the one I suggest, the speed of our imports increased drastically since the CPU could be used more to process messages instead of processing throws.

Upvotes: 12

Phani
Phani

Reputation: 5

how about trying mq.GetAllMessages().Length> 0

Upvotes: -2

blah
blah

Reputation: 399

MSMQ is not entirely interprocess communication. Interprocess communication is mostly in single machine but msmq can be used for different computers communicating. Guarenteed delivery, with flipside of having in same OS.

Upvotes: -1

Igal Serban
Igal Serban

Reputation: 10684

Update: I don't claim that performance is not important. But I think that inter process communication is very expensive in comparison to exception.

Before update:

  • I think that in the context of inter process communication( which is what msmq does) the cost of exception is unimportant. Test if you want to be sure.
  • I don't think so.

Upvotes: 1

Related Questions