Reputation: 6503
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.
Upvotes: 6
Views: 4346
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
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
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:
Upvotes: 1