![](/img/trans.png)
[英]Why is my RabbitMQ consumer (seemingly) consuming all messages at once?
[英]My C# WPF application consumer consuming all messages in a RabbitMQ Queue but some messages missing in the application
我为现有应用程序修复了错误。 原因:在应用程序侦听 RabbitMQ 队列时缺少消费消息。 如果应用程序打开/运行并将 10 条消息推送到队列,则所有消息都由应用程序消耗(队列消息清除),但 7,8 条消息仅通过应用程序出现(其他消息丢失)
但是如果 10 应用程序在应用程序关闭时发布到 rabbitMQ 队列。 然后在将所有 10 条消息发布到 RMQ 队列后打开应用程序,然后所有 10 条消息都被消费并正确保存在应用程序中。 这是一个已经开发的 WPF 应用程序,使用计时器来收听消息。
问题:
autoAck: false
in basic consumer & _channel.BasicAck(deliveryTag, false);
给我异常已经关闭:AMQP 操作被中断:AMQP 关闭原因,由 Application 发起,code=200,text='Goodbye',classId=0,methodId=0这是代码
主窗口.xmal.cs
public partial class MainWindow : Window
{
Thread _threadTimer;
private void Window_Loaded(object sender, RoutedEventArgs e)
{
_threadTimer = new Thread(() =>
{
dispatcherTimer.Tick += dispatcherTimer_Tick;
dispatcherTimer.Interval = new TimeSpan(0, 0, 1);
dispatcherTimer.Start();
});
_threadTimer.Start();
}
private void dispatcherTimer_Tick(object sender, EventArgs e)
{
#region rabbitMQ Configurtions
string HostName = hNamefromApp.config
string UserName = uNamefromApp.config
string Password = pwdfromApp.config
string QueueName = qNamefromApp.config
string VHost = vHostfromApp.config;
Thread _threadHandleMessage;
_threadHandleMessage = new Thread(() =>
{
HandleConsumeMessage(HostName, UserName, Password, QueueName, VHost, this.Dispatcher);
});
_threadHandleMessage.Start();
}
#endregion
}
private bool HandleConsumeMessage(string HostName, string UserName, string Password, string QueueName, string VHOST, Dispatcher dispatcher)
{
bool result = false;
var factory = CreateConnectionFactory(HostName, UserName, Password, VHOST);
using (var connection = factory.CreateConnection())
{
using (var channel = connection.CreateModel())
{
channel.QueueDeclare(queue: QueueName,
durable: false,
exclusive: false,
autoDelete: false,
arguments: null);
var response = channel.QueueDeclarePassive(QueueName);
var receivedMsgCount = response.MessageCount;
MessageReceiver messageReceiver = new MessageReceiver(channel, dispatcher, txtOutput);
channel.BasicConsume(queue: QueueName,
autoAck: true,
consumer: messageReceiver);
// Thread sleep duration calculate based on received message count
var consumeMsgCount = response.ConsumerCount;
int threadDuration = 300;
if (receivedMsgCount > 0)
{
threadDuration = (int)receivedMsgCount * 400;
}
Thread.Sleep(threadDuration);
}
}
return result;
}
}
消息接收器.cs
public class MessageReceiver : DefaultBasicConsumer
{
private readonly IModel _channel;
private readonly Dispatcher _dispatcher;
private readonly TextBox _textBox;
public MessageReceiver(IModel channel, Dispatcher dispatcher, TextBox textBox)
{
//Main thread and output text box is passed here so that this thread is capable of updating UI
_channel = channel;
_dispatcher = dispatcher;
_textBox = textBox;
}
Thread _threadConsumeMessage;
public override void HandleBasicDeliver(string consumerTag, ulong deliveryTag, bool redelivered, string exchange, string routingKey, IBasicProperties properties, ReadOnlyMemory<byte> body)
{
_threadConsumeMessage = new Thread(() =>
{
CaptureDataFromMessage(body);
});
_threadConsumeMessage.Start();
}
private void CaptureDataFromMessage(ReadOnlyMemory<byte> body)
{
try
{
var bodyArray = body.ToArray();
var message = Encoding.UTF8.GetString(bodyArray);
//LogModel txtLog = new LogModel();
//APIModel nlConsumeDetails = JsonConvert.DeserializeObject<APIModel>(message);
//Temporary save the consumed messages to local to test the issue
}
catch (Exception ex)
{
log.Error(ex);
}
}
}
您应该使用 Dispatcher.Invoke 从辅助线程更新您的 GUI。 使用不同的线程查看此更新 GUI (WPF)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.