Partilhar via


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

ArgumentException

The path syntax is not valid.

MessageQueueException

An error occurred when accessing a Message Queuing method.

-or-

The Exists(String) method is being called on a remote private queue

InvalidOperationException

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 Regards

  • Anonymous
    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 John

  • Anonymous
    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, Koen

  • Anonymous
    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?