【发布时间】:2022-01-30 19:17:49
【问题描述】:
我将 system.timers.timer 用于我的服务。
现在我构建了一个测试表单,我也在其中使用它。在 timer_Elapsed 事件中,我做了一些工作,想停止它需要的计时器(xxx ms)并将其写在要显示的表单控件上。
但是当我访问列表视图时,我得到一个跨线程错误。
有什么想法吗?
【问题讨论】:
我将 system.timers.timer 用于我的服务。
现在我构建了一个测试表单,我也在其中使用它。在 timer_Elapsed 事件中,我做了一些工作,想停止它需要的计时器(xxx ms)并将其写在要显示的表单控件上。
但是当我访问列表视图时,我得到一个跨线程错误。
有什么想法吗?
【问题讨论】:
使用 System.Timers.Timer 时,请使用计时器的SynchronizingObject 属性。显然,这会导致在创建指定组件 (SynchronizingObject) 的同一线程上调用处理 Elapsed 事件的方法。
例如。如果 myButton 是表单上的控件(无论是哪个主 GUI 线程),
System.Timers.Timer myTimer = new System.Timers.Timer();
myTimer.SynchronizingObject = this.myButton;
这会导致 Elapsed 处理程序在同一线程上运行,消除一些“跨线程操作”错误。
请注意:我对这是否是线程安全的知之甚少,但在特定用例中对我来说效果很好。无论如何,希望它有所帮助。
【讨论】:
如果要从主 UI 线程以外的线程访问控件,则需要对要访问的控件使用 Invoke 方法。
【讨论】:
你的方法应该是这样的:
public void foo(int value, string message)
{
if (InvokeRequired)
{
BeginInvoke(new Action<int, string>(foo), value, message);
}
else
{
// Stop the timer
}
}
【讨论】: