有没有办法检查MSMQ队列中有多少消息?

Jus*_*tin 39 c# msmq

我想知道是否有办法以编程方式检查使用C#在私有或公共MSMQ中有多少消息?我有代码,使用try/catch中包含的peek方法检查队列是否为空,但我从未见过有关显示队列中消息数的任何信息.这对于监视是否正在备份队列非常有用.

Gar*_*ght 34

您可以直接从.NET读取队列的性能计数器值:

using System.Diagnostics;

// ...
var queueCounter = new PerformanceCounter(
    "MSMQ Queue", 
    "Messages in Queue", 
    @"machinename\private$\testqueue2");

Console.WriteLine( "Queue contains {0} messages", 
    queueCounter.NextValue().ToString());
Run Code Online (Sandbox Code Playgroud)

  • 适用于一个队列,但对于错误队列我得到"实例'machinename\private $\error'在指定的类别中不存在." 是因为队列在队列中有一段时间没有任何项目,还是我需要以特殊的方式写入错误队列? (3认同)
  • 我在错误队列中添加了一条消息,然后代码也适用于该队列.我想你需要捕获这个异常(InvalidOperationException)然后它是空的.不好的是,如果你得到这个例外,队列也可能不存在. (2认同)

ole*_*sii 23

没有可用的API,但您可以使用GetMessageEnumerator2哪个足够快.样品:

MessageQueue q = new MessageQueue(...);
int count = q.Count();
Run Code Online (Sandbox Code Playgroud)

履行

public static class MsmqEx
{
    public static int Count(this MessageQueue queue)
    {
        int count = 0;
        var enumerator = queue.GetMessageEnumerator2();
        while (enumerator.MoveNext())
            count++;

        return count;
    }
}
Run Code Online (Sandbox Code Playgroud)

我也尝试了其他选择,但每个选项都有一些缺点

  1. 性能计数器可能抛出异常"实例'...'在指定的类别中不存在."
  2. 读取所有消息然后进行计数非常慢,它还会从队列中删除消息
  3. Peek抛出异常的方法似乎存在问题

  • 从某种意义上说,此方法似乎是线程安全的,它反映了队列的动态更改。来自[doc](https://goo.gl/GywJEn)*“例如,枚举器可以自动访问放置在光标当前位置之外的优先级较低的消息,但不能访问该位置之前插入的优先级较高的消息。 *。我个人在插入和删除期间正在负载下对其进行测试,并且没有线程问题。显然,这将反映大约。如果使用了队列,则消息计数。如果需要精确计数,则需要通过调用GetAllMessages获取静态快照。 (2认同)

Zar*_*tag 8

如果你需要一个快速的方法(在我的盒子上25k次/秒),我推荐基于MQMgmtGetInfo()和PROPID_MGMT_QUEUE_MESSAGE_COUNT的Ayende版本:

for C# https://github.com/hibernating-rhinos/rhino-esb/blob/master/Rhino.ServiceBus/Msmq/MsmqExtensions.cs

对于VB https://gist.github.com/Lercher/5e1af6a2ba193b38be29

起源可能是http://functionalflow.co.uk/blog/2008/08/27/counting-the-number-of-messages-in-a-message-queue-in/但我不相信这个从2008年开始实施工作.

  • 不要寻找其他答案!除了@Zartag的答案以外,任何其他方法都可能很慢或不可靠(我已经测试了所有方法,相信我!) (2认同)
  • nuget包[Rsft.Lib.Msmq.MessageCounter](https://www.nuget.org/packages/Rsft.Lib.Msmq.MessageCounter/)实现了这一点. (2认同)