更改 WindowsForms UI 在一个 Task 中 c#

huangapple go评论128阅读模式
英文:

Changing WindowsForms UI in a Task c#

问题

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.

  1. public Form1()
  2. {
  3. InitializeComponent();
  4. trainCount = 1;
  5. tagCount = 2;
  6. trains = new Train[trainCount];
  7. tags = new Tag[tagCount];
  8. InitializeTrains();
  9. InitializeTags();
  10. control = this;
  11. Task task = Handle_Received_Application_Message();
  12. }
  1. public async Task Handle_Received_Application_Message()
  2. {
  3. var mqttFactory = new MqttFactory();
  4. using (var mqttClient = mqttFactory.CreateMqttClient())
  5. {
  6. var mqttClientOptions = new MqttClientOptionsBuilder().WithTcpServer("127.0.0.1").Build();
  7. mqttClient.ApplicationMessageReceivedAsync += async e =>
  8. {
  9. Console.WriteLine("Received application message.");
  10. Console.WriteLine(e.ApplicationMessage.ConvertPayloadToString());
  11. for (int i = 0; i < tagCount; i++)
  12. {
  13. if (tags[i].code.CompareTo(e.ApplicationMessage.ConvertPayloadToString()) == 0)
  14. {
  15. for (int k = 0; k < trainCount; k++)
  16. {
  17. if (e.ApplicationMessage.ConvertPayloadToString().Substring(0, 2).CompareTo(trains[k].code) == 0)
  18. {
  19. Console.WriteLine("In Tag Event");
  20. trains[k].currentTag = tags[i];
  21. var message = e.ApplicationMessage.ConvertPayloadToString();
  22. await ChangeUI(); // Change UI is called here.
  23. }
  24. }
  25. }
  26. }
  27. };
  28. await mqttClient.ConnectAsync(mqttClientOptions, CancellationToken.None);
  29. var mqttSubscribeOptions = mqttFactory.CreateSubscribeOptionsBuilder()
  30. .WithTopicFilter(
  31. f =>
  32. {
  33. f.WithTopic("anten/main");
  34. })
  35. .Build();
  36. await mqttClient.SubscribeAsync(mqttSubscribeOptions, CancellationToken.None);
  37. Console.WriteLine("MQTT client subscribed to topic.");
  38. Console.ReadKey();
  39. }
  40. }
  1. public async Task ChangeUI()
  2. {
  3. if (InvokeRequired)
  4. BeginInvoke(new MethodInvoker(
  5. delegate
  6. {
  7. ChangeUI().Wait();
  8. }
  9. ));
  10. else
  11. {
  12. label1.Text = "sadasdasd"; // Code never reaches here.
  13. }
  14. }

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.

英文:

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.

  1. public Form1()
  2. {
  3. InitializeComponent();
  4. trainCount = 1;
  5. tagCount = 2;
  6. trains = new Train[trainCount];
  7. tags = new Tag[tagCount];
  8. InitializeTrains();
  9. InitializeTags();
  10. control = this;
  11. Task task = Handle_Received_Application_Message();
  12. }
  1. public async Task Handle_Received_Application_Message()
  2. {
  3. var mqttFactory = new MqttFactory();
  4. using (var mqttClient = mqttFactory.CreateMqttClient())
  5. {
  6. var mqttClientOptions = new MqttClientOptionsBuilder().WithTcpServer(&quot;127.0.0.1&quot;).Build();
  7. mqttClient.ApplicationMessageReceivedAsync += e =&gt;
  8. {
  9. Console.WriteLine(&quot;Received application message.&quot;);
  10. Console.WriteLine(e.ApplicationMessage.ConvertPayloadToString());
  11. for (int i = 0; i &lt; tagCount; i++)
  12. {
  13. if (tags[i].code.CompareTo(e.ApplicationMessage.ConvertPayloadToString()) == 0)
  14. {
  15. for (int k = 0; k &lt; trainCount; k++)
  16. {
  17. if (e.ApplicationMessage.ConvertPayloadToString().Substring(0, 2).CompareTo(trains[k].code) == 0)
  18. {
  19. Console.WriteLine(&quot;In Tag Event&quot;);
  20. trains[k].currentTag = tags[i];
  21. var message = e.ApplicationMessage.ConvertPayloadToString();
  22. ChangeUI(); //Change UI is called here.
  23. }
  24. }
  25. }
  26. }
  27. return Task.CompletedTask;
  28. };
  29. await mqttClient.ConnectAsync(mqttClientOptions, CancellationToken.None);
  30. var mqttSubscribeOptions = mqttFactory.CreateSubscribeOptionsBuilder()
  31. .WithTopicFilter(
  32. f =&gt;
  33. {
  34. f.WithTopic(&quot;anten/main&quot;);
  35. })
  36. .Build();
  37. await mqttClient.SubscribeAsync(mqttSubscribeOptions, CancellationToken.None);
  38. Console.WriteLine(&quot;MQTT client subscribed to topic.&quot;);
  39. Console.ReadKey();
  40. }
  41. }
  1. public void ChangeUI()
  2. {
  3. if (InvokeRequired)
  4. BeginInvoke(new MethodInvoker(
  5. delegate
  6. {
  7. ChangeUI();
  8. }
  9. ));
  10. else
  11. {
  12. label1.Text = &quot;sadasdasd&quot;; // Code never reaches here.
  13. }
  14. }

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.

答案1

得分: 2

Console.ReadKey 会阻止 Windows 消息循环执行,从而阻止任何 UI 更新。

我建议移除 Console.ReadKey,并且还要移除 Handle_Received_Application_Message 中的 using,以便不销毁客户端。而是在 Handle_Received_Application_Message 中创建一个成员变量来持有客户端,在应用程序开始关闭时进行销毁。

英文:

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.

huangapple
  • 本文由 发表于 2023年3月7日 21:32:31
  • 转载请务必保留本文链接:https://go.coder-hub.com/75662639.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定