Sending Messages that Request Acknowledgments

Acknowledgment messages are returned by MSMQ whenever the sending application requests them. To receive acknowledgment messages, the sending application must request the type of acknowledgment messages it wants returned (Ack) and an administration queue where MSMQ can send the acknowledgment messages (AdminQueueInfo).

The administration queue is maintained by the sending application. It is the sending application's responsibility to create the queue, to read the messages in the queue, and to perform whatever actions are required as a result of the type of acknowledgment message returned by MSMQ.

When reading the messages in the administration queue, the application can check the message's Class property to determine what type of acknowledgment was returned. Not all acknowledgment messages contain the same information. For example, although negative acknowledgment messages contain the message body of the original messages, positive acknowledgment messages do not. For a complete description of what is in the various types of acknowledgments, see Acknowledgment Messages.

Note  Each MSMQ message can have no more than 4 MB of data.

    To send messages that request acknowledgments
  1. Determine what type of acknowledgment messages need to be returned and which queue will be used as the administration queue.
  2. Locate the administration queue, creating one if it doesn't exist.
    Set qinfos = query.LookupQueue(Label:="Administration Queue")
    qinfos.Reset
    Set qinfoAdmin = qinfos.Next
    If qinfoAdmin Is Nothing Then
       Set qinfoAdmin = New MSMQQueueInfo
       qinfoAdmin.PathName = ".\AdminQueue"
       qinfoAdmin.Label = "Administration Queue"
       qinfoAdmin.Create
    End If
     
  3. Locate the destination queue, creating one if it doesn't exist.
    Set qinfos = query.LookupQueue(Label:="Destination Queue")
    qinfos.Reset
    Set qinfoDest = qinfos.Next
    If qinfoDest Is Nothing Then
       Set qinfoDest = New MSMQQueueInfo
       qinfoDest.PathName = ".\DestQueue"
       qinfoDest.Label = "Destination Queue"
       qinfoDest.Create
    End If
     
  4. Open the destination queue and send the message.
    Set qDest = qinfoDest.Open(MQ_SEND_ACCESS, MQ_DENY_NONE)
    msgSent.Label = "Test Message"
    msgSent.Body = "This message tests acknowledgment messages."
    msgSent.Ack = MQMSG_ACKNOWLEDGMENT_FULL_RECEIVE
    Set msgSent.AdminQueueInfo = qinfoAdmin
    msgSent.Send qDest
    
    MsgBox "The message was sent. Check the MSMQ Explorer to see the messages in the queue."
    
    qDest.Close
     
  5. Open the administration queue and read the acknowledgment messages returned by MSMQ. Messages are placed in the administration queue by their priority. The priority level of an acknowledgment message is set to the priority level of its original message.
    Set qAdmin = qinfoAdmin.Open(MQ_RECEIVE_ACCESS, MQ_DENY_NONE)
    Set msgAdmin = qAdmin.Receive
     
  6. Perform whatever actions are needed as a result of the returned acknowledgment message. The acknowledgment message's Class property specifies the type of acknowledgment returned.
    If msgAdmin.Class = MQMSG_CLASS_ACK_RECEIVE Then
          MsgBox "The message was removed from the queue."
    ElseIF msgAdmin.Class = MQMSG_CLASS_NACK_RECEIVE_TIMEOUT Then
          MsgBox "The message was not removed from the queue in time."
    Else
          MsgBox "The returned acknowledgment message (" + CStr(msgAdmin.Class) + ") is not valid for this example."
    End If
    

Example

This example uses an administration queue to see if a message has been retrieved from its destination queue. First a message is sent to its destination queue with its time-to-be-received timer (MaxTimeToReceive) set to 60 seconds. Then the application reads the acknowledgment message returned to the administration queue to see if the original message was retrieved from the queue. The destination and administration queues are created if they don't exist.

To try this example using Microsoft® Visual Basic® (version 5.0), paste the code into the Code window of a form, run the example, and click the form.

Dim query As New MSMQQuery
Dim qinfoDest As MSMQQueueInfo
Dim qinfoAdmin As MSMQQueueInfo
Dim qDest As MSMQQueue
Dim qAdmin As MSMQQueue
Dim msgSent As New MSMQMessage

Private Sub Form_Click()
   '****************************
   ' Locate administration queue
   '(create one if one doesn't
   ' exist).
   '****************************
   Set qinfos = query.LookupQueue(Label:="Administration Queue")
   qinfos.Reset
   Set qinfoAdmin = qinfos.Next
   If qinfoAdmin Is Nothing Then
      Set qinfoAdmin = New MSMQQueueInfo
      qinfoAdmin.PathName = ".\AdminQueue"
      qinfoAdmin.Label = "Administration Queue"
      qinfoAdmin.Create
   End If
         
   '***************************
   ' Locate destination queue
   '(create one if one doesn't
   ' exist).
   '***************************
   Set qinfos = query.LookupQueue(Label:="Destination Queue")
   qinfos.Reset
   Set qinfoDest = qinfos.Next
   If qinfoDest Is Nothing Then
      Set qinfoDest = New MSMQQueueInfo
      qinfoDest.PathName = ".\DestQueue"
      qinfoDest.Label = "Destination Queue"
      qinfoDest.Create
   End If
   
   '**************
   ' Open destination queue.
   '**************
   Set qDest = qinfoDest.Open(MQ_SEND_ACCESS, MQ_DENY_NONE)
   
   '**************
   ' Send Message.
   '**************
   msgSent.Label = "Test Message"
   msgSent.Body = "This message tests acknowledgment messages."
   msgSent.Ack = MQMSG_ACKNOWLEDGMENT_FULL_RECEIVE
   msgSent.MaxTimeToReceive = 60
   Set msgSent.AdminQueueInfo = qinfoAdmin
   msgSent.Send qDest
   qDest.Close
  
   '********************************
   ' Read Acknowledgment message in
   ' administration queue.
   '********************************
   Results = MsgBox("The message was sent to the queue. Click YES to remove the message from the queue and return a positive acknowledgment. Wait for 60 seconds and click NO to return a negative acknowledgment.", 4)
   If (Results = vbYes) Then
      Set qDest = qinfoDest.Open(MQ_RECEIVE_ACCESS, MQ_DENY_NONE)
      Set msgDest = qDest.Receive
   End If

   Set qAdmin = qinfoAdmin.Open(MQ_RECEIVE_ACCESS, MQ_DENY_NONE)
   Set msgAdmin = qAdmin.Receive
   
   If msgAdmin.Class = MQMSG_CLASS_ACK_RECEIVE Then
      MsgBox "The message was removed from the queue."
   ElseIf msgAdmin.Class = MQMSG_CLASS_NACK_RECEIVE_TIMEOUT Then
      MsgBox "The message was not removed from the queue in time."
   Else
      MsgBox "The returned acknowledgment message (" + CStr(msgAdmin.Class) + ") is not valid for this example."
   End If
 
End Sub