I wrote a windows forms application where I receive messages with MQTTNet from the broker. I want to change the UI according to the received message. But I couldn't make it happen. I took the client code from the MQTTNet github page. When I receive the message, I want to change a label. Because it is a task, I had to call the invoke function, but it never executes. The function to change the label is called, but the change statement is never reached.
public Form1()
{
InitializeComponent();
trainCount = 1;
tagCount = 2;
trains = new Train[trainCount];
tags = new Tag[tagCount];
InitializeTrains();
InitializeTags();
control = this;
Task task = Handle_Received_Application_Message();
}
public async Task Handle_Received_Application_Message()
{
var mqttFactory = new MqttFactory();
using (var mqttClient = mqttFactory.CreateMqttClient())
{
var mqttClientOptions = new MqttClientOptionsBuilder().WithTcpServer("127.0.0.1").Build();
mqttClient.ApplicationMessageReceivedAsync += e =>
{
Console.WriteLine("Received application message.");
Console.WriteLine(e.ApplicationMessage.ConvertPayloadToString());
for (int i = 0; i < tagCount; i++)
{
if (tags[i].code.CompareTo(e.ApplicationMessage.ConvertPayloadToString()) == 0)
{
for (int k = 0; k < trainCount; k++)
{
if (e.ApplicationMessage.ConvertPayloadToString().Substring(0, 2).CompareTo(trains[k].code) == 0)
{
Console.WriteLine("In Tag Event");
trains[k].currentTag = tags[i];
var message = e.ApplicationMessage.ConvertPayloadToString();
ChangeUI(); //Change UI is called here.
}
}
}
}
return Task.CompletedTask;
};
await mqttClient.ConnectAsync(mqttClientOptions, CancellationToken.None);
var mqttSubscribeOptions = mqttFactory.CreateSubscribeOptionsBuilder()
.WithTopicFilter(
f =>
{
f.WithTopic("anten/main");
})
.Build();
await mqttClient.SubscribeAsync(mqttSubscribeOptions, CancellationToken.None);
Console.WriteLine("MQTT client subscribed to topic.");
Console.ReadKey();
}
}
public void ChangeUI()
{
if (InvokeRequired)
BeginInvoke(new MethodInvoker(
delegate
{
ChangeUI();
}
));
else
{
label1.Text = "sadasdasd"; // Code never reaches here.
}
}
I tried creating a different thread when a message is received, but it didn't work neither.
Any help would be appreciated. I got stuck on this for 10 hours.
Console.ReadKey
will prevent the Windows message loop from executing, which prevents any UI updates.
I recommend removing Console.ReadKey
and also removing the using
in Handle_Received_Application_Message
so the client is not disposed. Instead of disposing the client in Handle_Received_Application_Message
, create a member variable to hold the client and dispose it when your application begins to shut down.