How can I remove messages from a queue?
Asked Answered
F

4

8

I have messages that get stuck in queue and I am looking for a way to programmatically remove them.

Is there a way to remove messages from a queue if it has been sitting for more than x days? I can connect and delete a queue like this, but not sure how to remove individual messages.

MessageQueue queue = new MessageQueue(@".\private$\SomeTestName");
//queue.Purge(); //deletes the entire queue
try
{
    // Peek and format the message. 
    Message m = myQueue.Peek();

   // Display message information.
   Console.WriteLine("Sent time {0}", m.SentTime);
   Console.WriteLine("Arrived time {0}", m.ArrivedTime);
}
Foreandafter answered 22/4, 2014 at 18:13 Comment(1)
possible duplicate of How to remove message from message queue (only if its well formatted)?Shelia
A
10

There is no API available to do this. But you can use

A benefit of using enumeration is that if a queue has many messages, reading all of them may result in OutOfMemoryException. With enumerator you only read 1 message at a time, and memory allocated for it can be reused.

Another trick to increase performance is to specify which properties to read, so that if the message body is large and you aren't interested in the content, you can disable reading it.

var enumerator = _queue.GetMessageEnumerator2();  // get enumerator
var staleDate = DateTime.UtcNow.AddDays(-3);      // take 3 days from UTC now    
var filter = new MessagePropertyFilter();         // configure props to read
filter.ClearAll();                                // don't read any property
filter.ArrivedTime = true;                        // enable arrived time
_queue.MessageReadPropertyFilter = filter;        // apply filter

// untested code here, edits are welcome
while (enumerator.Current != null)    
     if(enumerator.Current.ArrivedTime.Date >= staleDate)
         enumerator.RemoveCurrent();
     else
         enumerator.MoveNext();
Anticathexis answered 22/4, 2014 at 19:2 Comment(4)
what do you mean by "GetEnumerator2 does not dequeue messages?Turntable
MessageQueue does not contain a definition for removebyidForeandafter
No prob:), I get this error Property ArrivedTime was not retrieved when receiving the message on this line if (msg.ArrivedTime.Date >= staleDate) do you know why?Foreandafter
GetAllMessages does not dequeue either, rather it returns a static copy of the messages in the queue. @oleksii, however I agree with your comment regarding queue size: if it is a huge queue, you're much better off going with the GetEnumerator2 approach.Trinl
T
2

I think you can do something like this:

MessageQueue queue = new MessageQueue(@".\private$\SomeTestName");
var messages = queue.GetAllMessages();
var messagesToDelete = messages.Where(m => m.ArrivedTime < DateTime.Now.AddDays(-1)).ToList();
messagesToDelete.ForEach(m=>queue.ReceiveById(m.Id));

Obviously, you'll have to modify the date stuff to correspond with your scenario.

Trinl answered 22/4, 2014 at 18:31 Comment(0)
H
1

You could also use the ReceiveById method to remove the messages from the queue.

Check this link out: https://msdn.microsoft.com/en-us/library/system.messaging.messagequeue.receivebyid%28v=vs.110%29.aspx

How answered 22/12, 2015 at 14:26 Comment(0)
D
-1

Call GetAllMessages and add a check to find your message and do a delete operation on that message. Sample code,

    Message[] messages = msgQueue.GetAllMessages();
    foreach (Message msg in messages){
         doSomething();
    }
Deandeana answered 22/4, 2014 at 18:27 Comment(1)
You did not show how to remove a message from queue,Integrated

© 2022 - 2024 — McMap. All rights reserved.