【问题标题】:How to check if public MSMQ is empty如何检查公共 MSMQ 是否为空
【发布时间】:2010-09-10 16:14:13
【问题描述】:

有没有办法检查公共 MSMQ 是否为空?对于私有 MSMQ,这很容易:

private bool IsQueueEmpty(string path)
        {
            bool isQueueEmpty = false;
            var myQueue = new MessageQueue(path);
            try
            {
                myQueue.Peek(new TimeSpan(0));
                isQueueEmpty = false;
            }
            catch (MessageQueueException e)
            {
                if (e.MessageQueueErrorCode == MessageQueueErrorCode.IOTimeout)
                {
                    isQueueEmpty = true;
                }
            }
            return isQueueEmpty;
        }

如何对公共 MSMQ 进行同样的检查?如果我尝试使用上面的代码检查公共 MSMQ,它会给我一个 Peak 错误:

System.ArgumentOutOfRangeException:长度不能小于零。

【问题讨论】:

  • 我应该补充一下,公共 MSMQ 路径类似于 net.msmq://servername/mypublicqueue

标签: c# msmq netmsmqbinding


【解决方案1】:

我刚开始使用消息队列,但我的同事有一个很好的方法来检查队列是否为空:

if (MessageQueue.Exists(fullQueuePath))
{
    // FYI, GetMessageQueue() is a helper method we use to consolidate the code
    using (var messageQueue = GetMessageQueue(fullQueuePath))
    {
        var queueEnum = messageQueue.GetMessageEnumerator2();

        if (queueEnum.MoveNext())
        {
            // Queue not empty
        }
        else
        {
            // Queue empty
        }
    }
}

使用这种方法的好处是它不会抛出异常,而且我认为它不需要你等待超时发生。

【讨论】:

    【解决方案2】:

    Peek 方法仅在您使用直接格式名称访问队列时在远程计算机上可用。您应该能够使用相同的代码,只要您不依赖目录服务将您带到队列中。

    直接队列名称通常类似于:DIRECT=URLAddressSpecification/QueueName

    【讨论】:

    • 感谢您的回复。我以为每个公共队列都使用目录服务??我将路径更改为 DIRECT=TCP:myip\mypublicqueue 但它给了我:队列不存在或您没有足够的权限来执行操作
    • @Justin:直接名称类似于:DIRECT=OS:servername\public$\mypublicqueuenameDIRECT:TCP:ipaddress\public$\mypublicqueuename。您可以在 MSDN 中搜索要使用的特定直接格式名称 - 它可能因操作系统版本和其他因素而异。
    【解决方案3】:

    Leo,你确定吗?您不能在远程 Peek 中使用路径名吗?返回的错误没有说无效的格式名称,如果是这种情况,这是可以预料的。 事实上,错误似乎出现在“isQueueEmpty = false”行 - try/catch 不区分 peek 和 isQueueEmpty 行。 我敢打赌 isQueueEmpty 调用正在接收转换为负数的异常。 但是,现在您的解决方案可能是正确的 - MSMQ 中的许多远程调用需要格式名称而不是路径名称。因此,如果您使用格式名称来创建 myQueue,isQueueEmpty 应该可以工作。

    干杯

    约翰·布雷克韦尔

    【讨论】:

    • isQueueEmpty 是一个布尔值 - 我怀疑它会引发异常。至于Peek 的限制 - 我现在找不到文档,但我很确定有一个表格或其他东西可以识别Peek 何时可用。
    • 啊,当然,我看错了代码。难怪我在文档中找不到 isQueueEmpty !道歉。
    【解决方案4】:

    要检查队列是否为空,最简单的方法是使用方法:GetAllMessages()。如果消息为零,则队列为空。

     string queueName = ".\private$\testqueue";   
     if (MessageQueue.Exists(queueName))
     {   
        MessageQueue mq = new MessageQueue(queueName);
        var allMessages = mq.GetAllMessages();
        if (allMessages.Length > 0)
        {
             //Queue is not empty
        }
        else
        {
             //Queue is empty
        }
     }
     else
     {
          //Queue does not exist
     }
    

    【讨论】:

    • 欢迎来到 StackOverflow。虽然这段代码可以解决问题,including an explanation 解决问题的方式和原因确实有助于提高帖子的质量,并可能导致更多的赞成票。请记住,您正在为将来的读者回答问题,而不仅仅是现在提出问题的人。请edit您的答案添加解释并说明适用的限制和假设。
    猜你喜欢
    • 1970-01-01
    • 2014-03-13
    • 1970-01-01
    • 1970-01-01
    • 2017-11-15
    • 2020-05-29
    • 2018-04-02
    • 2016-04-05
    • 2018-01-08
    相关资源
    最近更新 更多