C# get number of messages in message queue (MSMQ)
Working with message queues in .net is incredibly easy. However I often find myself having to get the number of message in queue for monitoring, etc. That aspect of the message queue framework is a bit lacking. There are a few options available but they all have some problems.
You can call GetAllMessages() right off the message queue object. This code works, however it gets a copy of EVERY message queue item currently in the queue. Got 10 items, you get ten. Now do this with 10,000 items every second and it starts to become a problem.
It's also possible to enumerate through all the messages in the queue and take a count of them manually but if your queue is busy this can cause invalid cursor exceptions to happen. This is the main reason I moved away from doing this.
You can also do some performance counter work but I find that code to be too complex and very fragile and prone to breakage.
I've found the best bet is to go with the COM/Win32 route. The nice thing here is you don't have to do any PInoke calls but you do have to do some Marshalling. Now this code required the MSMQ 3.0 be installed. This is the latest version and should be fairly universal at this point in time.
First add a reference to the MSMQ 3.0 Object library to your project.
Now add a
statement to your class, etc.
The magic happens in the MSMQManagement class. The code below uses a MessageQueue I have already set up as m_imgRequestQueue. This is a standard .net MessageQueue object. In the future I will add the code on how to create a generic MessageQueue. For now this example assumes you know how to create a MessageQueue in .net. You create a new MSMQManagement class and set it up and then call the Init method. The machine name and formatName parameters are the only required params so that is why the path is set to null. After init you can then use the MessageCount property to access the number of messages in the queue. And as with any COM object in .NET you must always release it when you're done with it.
You can call GetAllMessages() right off the message queue object. This code works, however it gets a copy of EVERY message queue item currently in the queue. Got 10 items, you get ten. Now do this with 10,000 items every second and it starts to become a problem.
It's also possible to enumerate through all the messages in the queue and take a count of them manually but if your queue is busy this can cause invalid cursor exceptions to happen. This is the main reason I moved away from doing this.
You can also do some performance counter work but I find that code to be too complex and very fragile and prone to breakage.
I've found the best bet is to go with the COM/Win32 route. The nice thing here is you don't have to do any PInoke calls but you do have to do some Marshalling. Now this code required the MSMQ 3.0 be installed. This is the latest version and should be fairly universal at this point in time.
First add a reference to the MSMQ 3.0 Object library to your project.
Now add a
using MSMQ;
statement to your class, etc.
The magic happens in the MSMQManagement class. The code below uses a MessageQueue I have already set up as m_imgRequestQueue. This is a standard .net MessageQueue object. In the future I will add the code on how to create a generic MessageQueue. For now this example assumes you know how to create a MessageQueue in .net. You create a new MSMQManagement class and set it up and then call the Init method. The machine name and formatName parameters are the only required params so that is why the path is set to null. After init you can then use the MessageCount property to access the number of messages in the queue. And as with any COM object in .NET you must always release it when you're done with it.
// setup the queue management COM stuff
MSMQManagement _queueManager = new MSMQManagement();
object machine = new object();
machine = m_imgRequestQueue.MachineName;
object path = null;
object formatName = new object();
formatName = m_imgRequestQueue.FormatName;
_queueManager.Init( ref machine, ref path, ref formatName );
// once inited you can use the MessageCount property (int) to get the]
// number of messages in the queue
_queueManager.MessageCount
// ALWAYS release COM objects when you're done with them
Marshal.ReleaseComObject( _queueManager );
Comments
I'm running VS 2008 on Windows 7... any ideas where to get the DLL?
Thanks
1) at VS do the following
add reference -> browse
2) navigate to C:\Windows\SysWOW64
3) find mqoa30.tlb and select it
you now should succesfully be able to use it
I am left to wonder if it is a COM Interop object or a .NET Managed object.