with MessageEnumerator RemoveCurrent how do I know if I am at end of queue?
Asked Answered
S

1

7

In MSMQ on .NET, I'm using a MessageEnumerator to look through all the messages in the queue. I want to remove messages that meet a certain condition.

When I call MoveNext to step through the queue, I get back a boolean to tell me if the current message exists. But, when I do a RemoveCurrent, how do I know if the current message after the removal exists? Is the only way to check Current and handle the exception?

Here is an example where I use the simple condition of removing messages that are over one year old. Assume the queue was created elsewhere and set with MessageReadPropertyFilter.ArrivedTime = true:

private void RemoveOldMessages(MessageQueue q)
{
    MessageEnumerator me = q.GetMessageEnumerator2();
    bool hasMessage = me.MoveNext();
    while (hasMessage)
    {
        if (me.Current.ArrivedTime < DateTime.Now.AddYears(-1))
        {
            Message m = me.RemoveCurrent(new TimeSpan(1));
            // Removes and returns the current message
            // then moves to the cursor to the next message
            // How do I know if there is another message? Is this right?:
            try
            {
                m = me.Current;
                hasMessage = true;
            }
            catch (MessageQueueException ex)
            {
                hasMessage = false;
            }

        }
        else
        {
            hasMessage = me.MoveNext();
            // MoveNext returns a boolean to let me know if is another message
        }
    }
}
Symmetrical answered 18/2, 2014 at 19:58 Comment(0)
U
3

Albeit belated:

Every call to RemoveCurrent() will invalidate your Enumerator. As such you need to call Reset() to keep starting at the beginning of the Enumerator (Message Queue).

private void RemoveOldMessages(MessageQueue q)
{
    MessageEnumerator me = q.GetMessageEnumerator2();

    while (me.MoveNext())
    {
        try
        {
            Message m = me.RemoveCurrent();

            // Handle Message
        }
        finally
        {
            me.Reset();
        }
    }
}
Untrimmed answered 19/9, 2014 at 3:33 Comment(1)
This definitely should be the accepted answer. MSMQ documentation isn't clear on this and this is the first I've seen this solution. Ideally, RemoveCurrent shouldn't increment the counter.Lvov

© 2022 - 2024 — McMap. All rights reserved.