'Delete messages from MSMQ queue without iterating on all messages
I have a cleanup method triggered by a timer and each time I verify if I reach or not the max size defined in a configuration file.
The cleanup method will delete some messages from the queue when I reach the extra 5% of the max size, in a result, the method will delete hundreds of messages at once and I experience a huge percent of CPU usage at that time, I had an idea to make a Task.Delay between message deletion but I cannot use async / await
inside a ReaderWriterLockSlim
block, calling the timer more frequently is not a good solution as well since I'll iterate again on some 80 thousand messages, cannot filter the queue to delete them.
Another point is that each time I want to delete the oldest five minutes in the queue.
So, my question is, is there any deferred execution or some other optimization you suggest?
The code below illustrates the problem:
private void CleanupQueue(object state)
{
_lock.EnterWriteLock();
try
{
if (_localQueue != null)
{
var filter = new MessagePropertyFilter(); // configure props to read
filter.ClearAll(); // don't read any property
filter.ArrivedTime = true; // enable arrived time
_localQueue.MessageReadPropertyFilter = filter;
var messages = _localQueue.GetAllMessages();
if (!messages.Any())
{
return;
}
long size = _localQueue.GetSize();
long maxSize = _localSettings.QueueMaxSize * 1024 * 1024;
if (size <= maxSize * 1.05)
{
return;
}
_localQueue.MessageReadPropertyFilter.Body = true;
MessageEnumerator enumerator = _localQueue.GetMessageEnumerator2();
var oldestMessageDate = messages.Min(m => m.ArrivedTime);
var staleDate = oldestMessageDate.AddMinutes(5); // take oldest 5 minutes
while (enumerator.MoveNext(TimeSpan.Zero))
{
if (enumerator.Current is null || enumerator.Current.ArrivedTime > staleDate)
{
continue;
}
enumerator.RemoveCurrent();
enumerator.Reset();
}
}
}
catch (Exception e)
{
//error handling
}
finally
{
_lock.ExitWriteLock();
}
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|