从计时器更新 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 控件 [重复]的主要内容,如果未能解决你的问题,请参考以下文章