Can I peek into empty MSMQ without getting exception?
Asked Answered
H

4

6

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.

Heliogabalus answered 17/9, 2009 at 13:7 Comment(0)
D
1

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.
Dissolvent answered 17/9, 2009 at 18:50 Comment(2)
We pass messages through a pipeline of services where we use queues between them. We want to have the highest throughput possible, so it's not unimportant, but so far we have good enough performance.Transcurrent
I'll wait to see if I get any other comments, but if I don't I'll accept your answer :|Transcurrent
P
12
  • 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.

Portulaca answered 20/5, 2011 at 9:5 Comment(0)
D
1

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.
Dissolvent answered 17/9, 2009 at 18:50 Comment(2)
We pass messages through a pipeline of services where we use queues between them. We want to have the highest throughput possible, so it's not unimportant, but so far we have good enough performance.Transcurrent
I'll wait to see if I get any other comments, but if I don't I'll accept your answer :|Transcurrent
C
-1

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.

Carlitacarlo answered 10/12, 2009 at 15:48 Comment(0)
I
-2

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

Irena answered 5/10, 2010 at 9:22 Comment(1)
Really? Even when your queue may contain 1000's or 10.000's of large messages? That's like eating the whole supermarket empty just because you want to know wether they have any apples left.Beacham

© 2022 - 2024 — McMap. All rights reserved.