Get number of messages in MSMQ with C#

MSMQ message count in .NET

MSMQ (Microsoft Message Queuing) is a built in Windows component. It is not so popular now days as there are more efficient and robust solutions available.

However, it still has it's place in application architecture as a simple queueing system, plus as I mentioned, it comes out of the box with Windows operating system as a Windows component.
This means it is still widely used Windows based applications mostly for internal notifications and services between components of the solution. Latest version of MSMQ is 6.3 and it is built in in Windows 8.1 and Windows Server 2012 R2.

.NET framework supports MSMQ out of the box through System.Messaging namespace which is part of System.Messaging.dll assembly. Adding reference to this assembly you will be able to manipulate with message queues by instantiating System.Messaging.MessageQueue class.

One of the downsizes of this class is that it does not support count of messages currently in the queue.

Using MessageQueue.GetAllMessages()

Instead of count it supports pulling out all messages (not dequeuing them - they still stay in the queue) using MessageQueue.GetAllMessages() which returns an array of messages. Getting length of the result array can give you number of messages in the queue

var count = MessageQueue.GetAllMessages().Length;
    

This is inefficient way to get the message count because it requires to read all messages and store them in array which is in memory. This can cause cause huge memory consumption depending on the frequency, size of the message and current number of messages in the queue and can impact performances of the application. Essentially, you do not need messages, you only need count which is only a number.

Note

Using MessageQueue.GetAllMessages() to get number of messages in the queue is inefficient and should be avoided. Instead consider using other methods

Using WMI

MSMQ can be accesed through WMI (Windows Management Instrumentation) and by this it means that exposes API to .NET (more on this you can find on MSDN article Using WMI)

To test WMI queries you need to run wbemtest and click connect button in first and second window of the tool. You will be connected to your local machine MSMQ service.

Next click on query button and type the query to get the queue object you want to check where [QUEUE NAME] is the name of your queue you want to check for message count

SELECT Name,MessagesinQueue FROM Win32_PerfRawdata_MSMQ_MSMQQueue WHERE Name LIKE '%[QUEUE NAME]$'
    

Now to execute this from .NET code we first need to add reference to System.Management assembly to our project. Then simply reference it in the code and execute query from above

private static long GetMessaegCount(String msmqName)
{
ManagementObjectSearcher wmiSearch = new ManagementObjectSearcher(String.Format("SELECT Name,MessagesinQueue FROM Win32_PerfRawdata_MSMQ_MSMQQueue WHERE Name LIKE '%{0}$'",msmqName));
ManagementObjectCollection wmiCollection = wmiSearch.Get();
foreach (ManagementObject wmiObject in wmiCollection)
{
foreach (PropertyData wmiProperty in wmiObject.Properties)
{
if (wmiProperty.Name.Equals("MessagesinQueue", StringComparison.InvariantCultureIgnoreCase))
                    {
                        return long.Parse(wmiProperty.Value.ToString());
                    }
                }
            }
            throw new ArgumentException(String.Format("MSMQ with name {0} not found",msmqName));
        }
    

Using Enumerator of MessageQueue class

Second approach how to get number of message of the MSMQ is to actually loop through the queue using enumerator provided by MessaegQueue class itself.

using System.Messaging;

namespace MsmmqTests.Extensions
{
    public static class Methods
    {
        public static long Count(this MessageQueue messageQueue)
        {
            var enumerator = messageQueue.GetMessageEnumerator2();
            long counter = 0;
            while (enumerator.MoveNext())
            {
                counter++;
            }
            return counter;
        }
    }
}

    

The method is static and it is written to extend the System.Messaging.MessageQueue class. This means that any instance of System.Messaging.MessageQueue class in your code will have this method if you add using of MsmmqTests.Extensions namespace.

The following example shows how to easily consume the previous extension method on the System.Messaging.MessageQueue class.

using System.Linq;
using System.Messaging;
using MsmmqTests.Extensions;
namespace MsmmqTests
{
    class Program
    {
        static void Main(string[] args)
        {
            MessageQueue messageQueue = new MessageQueue(@".\Private$\myqueue");
            messageQueue.Count();
        }
    }
}

    
Note

Since we rely on looping through the queue, keep in mind that this takes certain amount of time and resources to execute and return results.

 

References

Disclaimer

Purpose of the code contained in snippets or available for download in this article is solely for learning and demo purposes. Author will not be held responsible for any failure or damages caused due to any other usage.


About the author

DEJAN STOJANOVIC

Dejan Stojanovic is a passionate Software Architect/Developer. He is highly experienced in .NET programming platform includion ASP.NET MVC and WebApi. He likes working on new technologies and exciting challenging projects

CONNECT WITH DEJAN Loginlinkedin Logintwitter Logingoogleplus Logingoogleplus

JavaScript

read more

SQL/T-SQL

read more

Umbraco CMS

read more

PowerShell

read more

Comments for this article