据我在文档中看到,您应该检查消息队列中是否有消息的方式是使用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;
}
Run Code Online (Sandbox Code Playgroud)
我总是被告知 - 并且经历过 - Exeptions价格昂贵,不应该用于正常操作.所以我的问题是:
我依赖捕获MessageQueueException的假设是否代价高昂?
有没有办法同步检查队列中是否有消息而不必依赖异常?
我正在使用C#中的System.Messaging命名空间,但是如果我需要不受管理来解决这个问题,那么这可能是一个选项.请注意,我想要一个不使用WCF和MSMQ的解决方案.
Osk*_*erg 12
是的,你认为异常代价高昂是正确的.实际上这是投掷是昂贵的,而不是捕捉.队列有时是空的是正常的,正常状态不应该导致抛出异常.
通过使用MessageQueue.GetMessageEnumerator2,我们可以使用枚举器来确定队列是否为空而不加载所有消息.使用这种方法,我们永远不会加载多条消息.
例:
private static bool IsQueueEmpty(MessageQueue queue)
{
using (var enumerator = queue.GetMessageEnumerator2())
{
return !enumerator.MoveNext();
}
}
Run Code Online (Sandbox Code Playgroud)
或者实现Peek,如果消息队列为空,则返回null(未经测试但应该工作)
private static Message Peek(MessageQueue queue)
{
using (var enumerator = queue.GetMessageEnumerator2())
{
return enumerator.MoveNext() ? enumerator.Current : null;
}
}
Run Code Online (Sandbox Code Playgroud)
我们使用原始代码来检查大约20个不同的队列.由于我们从原始实现更改为我建议的实现,因此可以大大增加我们的导入速度,因为CPU可以更多地用于处理消息而不是处理抛出.
更新:我并不是说性能不重要。但我认为与异常相比,进程间通信的成本非常高。
更新前:
| 归档时间: |
|
| 查看次数: |
3683 次 |
| 最近记录: |