Can I peek into empty MSMQ without exception?

As far as I understand from the documentation, you should check if there are messages in the message queue, use the Peek method. Then you rely on this with a MessageQueueException error to tell you that the queue is 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 have always been told - and experienced - that Exceptions are expensive and should not be used for routine operations. So my questions are:

  • Are my assumptions that using a MessageQueueException is an expensive operation?

  • Is there a way to synchronously check if there are messages in the queue without relying on exceptions?

I work with the System.Messaging namespace in C #, but if I need to be unmanaged to solve this problem, this might be an option. And note that I want a solution without using WCF with MSMQ.

+6
msmq
source share
4 answers

Update: I am not saying that performance is not important. But I think that the interaction between the processes is very expensive compared to the exception.

Before updating:

  • I think that in the context of the interaction between processes (which is msmq), the cost of an exception does not matter. Check if you want to be sure.
  • I do not think so.
+1
source share
  • Yes, you are correct in assuming that exceptions are costly. This is actually a cast that is expensive rather than catching. Typically, a queue should be empty from time to time, and a normal state should not result in an exception being thrown.

  • Using MessageQueue.GetMessageEnumerator2, we can use a counter to determine if the queue is empty or not without loading all messages. With this approach, we will never upload more than one message.

Example:

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

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

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

We used a code similar to the original to check about twenty different queues. Since we changed the initial implementation to the one I propose, the speed of our import increased sharply, since the processor could be used more for processing messages instead of processing throws.

+11
source share

MSMQ is not completely interprocess. Interprocess communication mainly runs on the same machine, but msmq can be used to communicate on different computers. Guarenteed delivery, with a reverse location in the same OS.

-one
source share

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

-2
source share

All Articles