【发布时间】:2021-08-27 12:27:46
【问题描述】:
我一直在尝试制作一个 Windows 应用程序,当我收到一条消息“some_string”(来自服务器)时,我需要将标签的颜色(代码中的 sys2lbl)更改为绿色,并且它会保持绿色 15秒,然后变红。但是,例如,在第 5 秒内,如果我再次收到消息“some_string”,则标签应保持绿色多 15 秒,即总共 5+15 = 20。
我正在使用Task.Run(),根据我的理解,当我在这15秒内收到字符串'some_string'时,这个任务会以某种方式重新启动。
注意:如果我在 15 秒后收到“some_string”,此任务将完美运行。
有人知道怎么解决吗?
Task.Run(() =>
{
if (x.ApplicationMessage.Topic == "some_string")
{
sys2lbl.BackColor = Color.Green;
Thread.Sleep(15000);
sys2lbl.BackColor = Color.Red;
}
});
【问题讨论】:
-
我对@987654323@ 的理解是,它确实使您正在与之交互的线程处于休眠状态。在时间框架过去之前,您不能对该线程执行任何其他操作 - 这就是为什么 Thread.Sleep 在很多情况下不一定是一个好主意。看起来你可能想要
Timer类的一些行为:docs.microsoft.com/en-us/dotnet/api/… -
在实践中当我收到来自服务器的消息时是什么意思?您是在轮询 API 还是服务器推送它?即,您是否有一种分派到 UI 线程的 Message Loop?还是事件驱动?异步? -- 如果需要启动后台线程来轮询服务器,则需要在 UI 线程中调用委托。那是您设置控件状态的地方(不是来自另一个线程/任务)。您可以在 UI 线程中使用 Timer,如果它仍然处于活动状态,则将其
Interval增加 5 秒,否则只需启动它。 -- 如果你真的需要一个不同的线程。 -
我制作的 UI 订阅了 MQTT 服务器中的主题。因此,消息以随机方式发布在服务器中。每当我订阅一个特定主题时,标签应该变成绿色并保持一段时间然后变成红色。
-
那么,您是否使用经纪人的发布功能订阅特定主题?然后,您应该通过事件接收新消息,该事件在 UI 线程以外的线程中引发。您可以使用在 UI 线程中创建的委托将新数据编组到 UI 线程。当接收到事件时,您可以使用
IProgrsss<T>委托或Invoke()/BeginInvoke()您自己的委托(您需要测试同步版本是否比异步版本更可靠)。如上所述,委托要么启动计时器,要么增加其间隔。 -
顺便说一句,不要用不相关的
cancellationtoken或诸如此类(好像你是 建议 解决方案)标记你的问题,你为什么不标记它mqtt和发布您用来接收发布者通知的代码?您的客户也是发布者吗?即,您可能需要解决一些竞争条件。
标签: c# winforms cancellationtokensource cancellation-token