Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I peek into empty MSMQ without getting exception?

Tags:

msmq

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:

  • Are my assumptions that relying on catching the MessageQueueException is a costly operation correct?

  • Are there any way to synchronously check if there are messages in a queue without having to rely on exceptions?

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.

like image 390
Torbjørn Avatar asked Sep 17 '09 13:09

Torbjørn


People also ask

What is Peek in message queue?

The Peek() method is synchronous, so it blocks the current thread until a message becomes available or the specified time-out occurs. Peek(TimeSpan, Cursor, PeekAction) Returns without removing (peeks) the current or next message in the queue, using the specified cursor.

Is MSMQ asynchronous?

Asynchronous messaging. With MSMQ asynchronous messaging, a client application can send a message to a server and return immediately, even if the target computer or server program is not responding.

How do I send a message to MSMQ?

To send a message to MSMQ, create an instance of the MessageQueue class and call the Send method that passes in the Message object. The MessageQueue class is the wrapper that manages the interaction with MSMQ. The syntax for setting the path of the private queue that you created in the Computer Management console.

Why do we use MSMQ?

Message Queuing (MSMQ) technology enables applications running at different times to communicate across heterogeneous networks and systems that may be temporarily offline. Applications send messages to queues and read messages from queues.


1 Answers

  • 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.

like image 88
Oskar Sjöberg Avatar answered Sep 22 '22 03:09

Oskar Sjöberg