Deleting a public queue doesn't stop MSMQ sending messages

Public queues, as opposed to private queues, don't delete as quickly as you'd expect. Sometimes it can take a full quarter of an hour before the queue you've just deleted finally disappears.

Looking at:

Message Queuing (MSMQ): Directory Service Change Notification Protocol Specification

and scrolling down to page 37 you will find Note #25 which says:

"<25> Section 3.1.4.4: On Windows NT and Windows 2000, queue managers process notification messages as soon as they arrive. In contrast, on Windows XP, Windows Server 2003, and Windows Vista, queue managers process notification messages as soon as they arrive for messages from directory services and schedule notification messages to be processed at specific time intervals for messages from queue managers. Notification messages from queue managers are processed at a maximum rate of once per 15 minutes to prevent denial of service attacks."

To explain this further, I'll use an example.

  • Machine HOST runs MSMQ and has a queue called STOCK
  • Machine ADMIN runs MSMQ and "Active Directory: Users and Computers".
  • Machine OURDC is the Active Directory domain controller.

The steps are as follows:

  1. An administrator sitting at ADMIN uses "AD:Users and Computers " to delete the STOCK public queue.
  2. The corresponding queue object is deleted from Active Directory.
  3. The MSMQ queue manager on ADMIN sends an internal notification message (containing the object GUID of the queue to be deleted) to the private queue called notify_queue$ on HOST. Being an internal queue, you won't be able to see this message except in a Network Monitor trace.
  4. The MSMQ queue manager on HOST receives and processes the message.
  5. If HOST has not received any other notifications recently then it's queue manager will contact OURDC immediately to determine the status of the queue olther it will wait 15 minutes.
  6. After querying OURDC over LDAP, the STOCK queue is deleted.

So how can you delete a queue and get messages to stop being delivered at the same time?

This really depends on how many machines are sending messages. 10? 100? 1,000?

Here are a few examples:

  • If there are only a few senders then you could pause the appropriate outgoing queue. There would have to be some signalling mechanism to enable this, such as a thread watching an admin queue for pause requests from the application that needs to delete the public queue.
  • The destination's MSMQ service could be taken off-line but that would affect all the other hosted queues too.
  • Use private instead of public queues (although that does eliminate some functionality, such as authentication and encryption).