Checking if MSMQ queues exist is hard work so should you bother?
Frank Boyne, 5 star MVP, posted a great response to a question on the MSMQ newsgroups which I felt was worth reiterating.
Basically someone wanted to check if a private queue on a remote machine existed before they sent a message to it. The problem was that they couldn't call the MessageQueue.Exists() method without getting InvalidOperationException.
As Frank explained, this method call isn't available for remote computers, as documented in MSDN.
Exception |
Condition |
The path syntax is not valid. |
|
An error occurred when accessing a Message Queuing method. -or- The Exists(String) method is being called on a remote private queue |
|
The application used format name syntax when verifying queue existence. |
As you can see, an exception will be thrown for checking remote private queues.
The interesting part of Frank's response is what to do about it. Basically, checking that a remote queue exists before you send is no guarantee that the destination will still be there when the message arrives. Or, vice versa, someone could create the queue just after you've found it didn't exist.
Frank's alternative approach is to make use of other features that MSMQ provides, such as negative acknowledgements messages with administration queues.
What should happen is that either:
- the message will be delivered successfully to the destination queue
or - a negative acknowledgement (NACK) will be returned to the administration queue with a class of "The destination queue does not exist." (MQMSG_CLASS_NACK_BAD_DST_Q)
Alternatively you could use negative source journaling and, on failure to deliver, should see the same class of NACK in the corresponding "Dead-letter messages" system queue.
In summary, don't check if the queue exists but instead handle the non-delivery of the message should it turn out that the queue doesn't exist.
Comments
Anonymous
January 09, 2009
Hi, Is is possible to use MSMQ ping utility through DotNet code to acheive the same thing. I am actually looking for checking the satus of remote public queue using direct format name. Thanks in advance RegardsAnonymous
January 14, 2009
Hi Sharad, The MSMQ Ping utility, as documented here (Test connectivity using MQPing (http://technet.microsoft.com/en-us/library/cc739689.aspx) doesn't have an API for you to call it. And even if you could, it requires Active Directory so is going to be using pathname under the covers. So it's a great idea but I'm afraid you will have to rely on your own implementation as discussed in the blog post. Cheers JohnAnonymous
August 16, 2009
Hi, Actually it is very simple : make an instance of a messagequeue class and ask the queuename. You get a messagequeueexception if it does not exists. If you capture that exception at a predifined place, it 's a very easy thing todo. Greetz, KoenAnonymous
August 16, 2009
Hi Koen, Could you please supply a sample of what you mean as I don't understand how your suggestion will work for private queues on remote machines. Cheers John Breakwell (MSFT)Anonymous
August 21, 2009
During Application startup we check the CanWrite property is true documented here: http://msdn.microsoft.com/en-us/library/system.messaging.messagequeue.canwrite.aspx which should work if your using the direct format name for the queue's (though i just tested with Formatname:DIRECT=OS:nonhostprivate$masterqueue and it "CanWrite" and an outgoing queue is waiting for that machine, which will never come) Doubt that has helped at all...Anonymous
March 28, 2010
But interestingly, it appears that CanRead is always false even if CanWrite is always true when using a remote private Q. Do you suppose there are any problems with relying on that?