我使用RabbitMQ从队列中提供消费项目。我的应用程序由Windows服务处理,大部分时间都在运行。
在服务START(OnStart)上我使用方法
while (true)
{
var ea =(BasicDeliverEventArgs)consumer.Queue.Dequeue();
// ... Handle this item
}
为了消耗队列中的项目。功能' Dequeue()'阻止。线程将在此行中被阻止,直到某个项目到达。
当我试图实现我的服务的OnStop方法时,我的问题就开始了。我的目标是在OnStop信号到达时停止等待新项目。所以,我修改了我的代码:
while (true)
{
if (this.IsStopping)
return; // OnStop signal arrived. Stop waiting.
var ea =(BasicDeliverEventArgs)consumer.Queue.Dequeue();
// ... Handle this item
}
在某些情况下,上面的代码工作正常。但是,如果队列为空,则不会执行Windows服务。
您如何建议我解决此问题?
答案 0 :(得分:2)
你有两种方法可以做到这一点,第一种方法叫做#34;有毒消息",在停止服务期间你向队列发送消息:
while (true)
{
var ea =(BasicDeliverEventArgs)consumer.Queue.Dequeue();
// ... Handle this item
if (mymessage is MyPoisonMessage)
break;
}
其实我不喜欢,但这是一个快速的解决方案。
另一个是扩展类DefaultBasicConsumer
然后使用消费者标记来关闭消费者,类似于:
class SampleConsumer : DefaultBasicConsumer
{
public SampleConsumer(IModel channel) : base(channel)
{
}
public override void HandleBasicDeliver(string consumerTag, ulong deliveryTag, bool redelivered, string exchange, string routingKey,
IBasicProperties properties, byte[] body)
{
.....
然后实例化该类,获取consumerTag
并以这种方式关闭它:
channel.BasicCancel(consumerTag)
希望它有所帮助。