从计时器更新 Winforms 控件 [重复]

Posted

技术标签:

【中文标题】从计时器更新 Winforms 控件 [重复]【英文标题】:Update Winforms controls from Timers [duplicate] 【发布时间】:2020-08-29 22:57:57 【问题描述】:

我正在尝试更好地理解 Forms.Timers。 据我了解,计时器是在线程池中的线程上执行的,在这种情况下,您不应从计时器更新表单上的控件(因为这不是创建此控件的线程)。

但是,在 microsoft (https://docs.microsoft.com/en-us/dotnet/framework/winforms/controls/run-procedures-at-set-intervals-with-wf-timer-component) 提供的示例中,它们正在从计时器更新控件。

所以,我的问题是,从计时器(没有 control.Invoke 调用)更新控件(如标签)是否有任何问题?

如果不是,为什么不呢? (因为这是线程池中的线程,而不是创建控件的线程)

【问题讨论】:

注意! System.Timers.Timer != System.Threading.Timer != System.Windows.Forms.Timer ... .NET 平台内置了许多Timer 类,位于不同的命名空间中。看看here(向下滚动到绿色的提示部分)。你指的定时器是什么类型的? 您绝对可以使用 Forms.Timer 更新表单控件。请尝试并查看,如果您遇到特定问题,请返回。 【参考方案1】:

Windows.Forms.Timer 已优化以与 UI 一起使用。

从上面的链接。强调我的:

计时器用于以用户定义的时间间隔引发事件。 此 Windows 计时器专为使用 UI 线程执行处理的单线程环境而设计。它要求用户代码具有可用的 UI 消息泵,并且始终从同一线程运行,或将调用编组到另一个线程。

System.Timers.Timer 有一个 SynchronizingObject,如果您想使用它,可以将其设置为表单对象。

来自上面的链接:

当 SynchronizingObject 为 null 时,将在系统线程池中的线程上调用处理 Elapsed 事件的方法。有关系统线程池的更多信息,请参阅 ThreadPool。 当 Elapsed 事件由可视化 Windows 窗体组件(例如按钮)处理时,通过系统线程池访问组件可能会导致异常或可能无法正常工作。 通过将 SynchronizingObject 设置为 Windows 窗体组件来避免这种影响,这会导致在创建该组件的同一线程上调用处理 Elapsed 事件的方法。

【讨论】:

以上是关于从计时器更新 Winforms 控件 [重复]的主要内容,如果未能解决你的问题,请参考以下文章

WPF Timer 控件在哪里?

WinForms 中的计时器

Winforms 傻瓜计时器

MFC如何在对话框内加入计时器并实时显示出来?

Vue.js 自定义组件封装实录——基于现有控件的二次封装(以计时器为例)

带有计时器和字符串替换的Python请求[重复]