据我在文档中看到,您应该检查消息队列中是否有消息的方式是使用Peek方法。然后,您依靠它失败并返回MessageQueueException来告诉您队列为空。
public bool IsQueueEmpty()
{
bool isQueueEmpty = false;
MessageQueue myQueue = new MessageQueue(".\\myQueue");
try
{
myQueue.Peek(new TimeSpan(0));
isQueueEmpty = false;
}
catch(MessageQueueException e)
{
if (e.MessageQueueErrorCode ==
MessageQueueErrorCode.IOTimeout)
{
isQueueEmpty = true;
}
}
return isQueueEmpty;
}
我总是被告知 - 并且经历过 - Exeptions价格昂贵,不应该用于正常操作。所以我的问题是:
我依赖捕获MessageQueueException的假设是否是一项代价高昂的操作?
有没有办法同步检查队列中是否有消息而不必依赖异常?
我正在使用C#中的System.Messaging命名空间,但如果我需要不受管理来解决这个问题,那么这可能是一个选项。请注意,我想要一个不使用带有MSMQ的WCF的解决方案。
答案 0 :(得分:12)
是的,你认为异常代价高昂是正确的。实际上这是投掷是昂贵的,而不是捕捉。队列有时是空的是正常的,正常状态不应该导致抛出异常。
通过使用MessageQueue.GetMessageEnumerator2,我们可以使用枚举器来确定队列是否为空而不加载所有消息。使用这种方法,我们永远不会加载多条消息。
示例:
private static bool IsQueueEmpty(MessageQueue queue)
{
using (var enumerator = queue.GetMessageEnumerator2())
{
return !enumerator.MoveNext();
}
}
或实现Peek,如果消息队列为空(未经测试但应该有效),则返回null
private static Message Peek(MessageQueue queue)
{
using (var enumerator = queue.GetMessageEnumerator2())
{
return enumerator.MoveNext() ? enumerator.Current : null;
}
}
我们使用原始代码来检查大约20个不同的队列。由于我们从原始实现更改为我建议的实现,因此我们的导入速度急剧增加,因为CPU可以更多地用于处理消息而不是处理抛出。
答案 1 :(得分:1)
更新:我并不认为性能不重要。但我认为与异常相比,进程间通信非常昂贵。
更新前:
答案 2 :(得分:-1)
MSMQ不是完全进程间通信。进程间通信主要在单机中,但msmq可用于不同的计算机通信。保证交付,与在相同的操作系统中相反。
答案 3 :(得分:-2)
如何尝试mq.GetAllMessages()。长度> 0