Although cursors are independent, how they are used may affect a message that another cursor is pointing to. For example, if two cursors are pointing at the same message and one cursor is used to remove the message, the other cursor no longer points to a message. An error is returned if an attempt is made to peek at or retrieve the message that was removed.
Note A cursor pointing to a message does not guarantee that the message always exists. The message can be removed by another cursor, another application, by MSMQ Explorer, or the queue could be deleted.
The relationship between message position and cursor position can be simple or complex depending on how the messages in the queue are read. The following illustrations show several scenarios, starting with the simple case of retrieving the first message in the queue (using no cursor), and ending with an example of multiple cursors. Each example shows message and cursor position before and after the call was made.
Note Cursors work the same way for synchronous and asynchronous operations. However, you should not use the same cursor when firing receives in overlapping operations. Firing a second receive (using the same cursor) before the first one is completed leads to unexpected behavior.
Here no cursor is used to remove Message A from the queue. The cursor shown in the illustration could be another application's cursor or the implied cursor used by ActiveX applications.
Platform | |
---|---|
C: | MQReceiveMessage dwAction==MQ_ACTION_RECEIVE hCursor==NULL |
ActiveX | MSMQQueue.Receive |
Here a cursor is used to look at the second message in the queue. The message is peeked at but not removed from the queue. Cursor position and message position remain the same.
Platform | |
---|---|
C: | MQReceiveMessage dwAction==MQ_ACTION_PEEK_CURRENT hCursor==<CurrentCursorHandle> |
ActiveX | MSMQQueue.PeekCurrent |
Here a cursor is used to retrieve the second message in the queue. When the call is made, the message is removed from the queue and the cursor now points at a new message. When the last message in a queue is retrieved, MSMQ points the cursor to the end of the queue and waits for a new message or a time-out to occur.
Platform | |
---|---|
C: | MQReceiveMessage dwAction==MQ_ACTION_RECEIVE hCursor==<CurrentCursorHandle> |
ActiveX | MSMQQueue.ReceiveCurrent |
Here a cursor is used to peek at the next two messages in the queue. When the first call is made, MSMQ moves the cursor and then looks at the new message. When the second call is made (the cursor is pointing to the last message in the queue), MSMQ moves the cursor to the end of the queue and waits for a new message or a time-out to occur.
Platform | |
---|---|
C: | MQReceiveMessage dwAction==MQ_ACTION_PEEK_NEXT hCursor==<CurrentCursorHandle> |
ActiveX | MSMQQueue.PeekNext |
Here one cursor is pointing at a message (CursorB) in the queue and another cursor (CursorA) is removing messages from the queue. CursorA removes messages from the queue with several receive calls while CursorB remains pointing to message "C." After CursorA removes message "C", CursorB no longer points to a message. CursorB is now pointing to a message placeholder, and an error is returned if the application tries to read a message at the current CursorB location. However, CursorB can still be used if peek-next is called.
Platform | |
---|---|
C: | MQReceiveMessage dwAction==MQ_ACTION_RECEIVE hCursor==<CurrentCursor1Handle> |