I got a bug fixing for an existing application. Reason: Missing consume messages when application listening for a RabbitMQ Queue. If the application opens/running and push 10 messages to the queue, then all the messages consume by Application (Queue messages get clear) but 7,8 messages only appear through the application (and others are missing)
But if 10 the application publishes to the rabbitMQ queue while the Application close. Then opens the application after published all 10 messages to RMQ queue, Then all 10 messages are consumed and save in the application correctly. This is an already developed WPF application using a timer to listen to messages.
Questions:
autoAck: false
in basic consumer & _channel.BasicAck(deliveryTag, false);
gives me exception Already closed: The AMQP operation was interrupted: AMQP close-reason, initiated by Application, code=200, text='Goodbye', classId=0, methodId=0This is the code
MainWindow.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;
}
}
MessageReceiver.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);
}
}
}
You should use Dispatcher.Invoke to update your GUI from a secondary thread. See this Updating GUI (WPF) using a different thread
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.