使用Timer的跨线程操作错误class
Cross-thread operation error using a Timer class
我的代码中出现上述错误。当我使用 windows 表单的计时器时,我能够成功 运行 我的应用程序。现在改成system.timers了,不知道哪里做错了。我正在实施 IMessageFilter 以收听 mouse/keyboard 移动并在有交互时重新启动计时器。如果没有交互,则隐藏表单。拜托,有人可以帮帮我吗?我正在使用 VB.Net,这是我正在使用的代码:
从表单加载
Application.AddMessageFilter(Me)
timerTest= New System.Timers.Timer()
AddHandler timerTest.Elapsed, AddressOf OnTimedTestEvent
timerTest.Enabled = True
实施 IMessageFilter
Public Function PreFilterMessage(ByRef m As Message) As Boolean Implements IMessageFilter.PreFilterMessage
If (m.Msg >= &H100 And m.Msg <= &H109) Or (m.Msg >= &H200 And m.Msg <= &H20E) Then
timerTest.Stop()
timerTest.Interval = 30000
timerTest.Start()
End If
End If
End Function
事件触发器
Private Sub OnTimedTestEvent(source As Object, e As ElapsedEventArgs)
timerTest.Stop()
HideForm()
End Sub
隐藏表格
Private Sub HideForm()
Me.Visible = False <--- getting error here
End Sub
只允许 UI 线程更改 UI 对象。这是 WinForms 的已知限制。
然而,Forms.Timer
class will keep code running in the UI's message pump, meaning you won't ever have to worry about cross-threading calls. Timers.Timer
使用自己的线程。
要获得您想要的行为,您可能需要继续使用 WinForm 的 Forms.Timer
class 或将您的 HideForm()
方法更改为:
Private Sub HideForm()
If Me.InvokeRequired Then
Me.Invoke(New Action(Sub() Me.HideForm()))
Else
Me.Visible = False
End If
End Sub
InvokeRequired
boolean property checks if the code is currently being run on another thread than the UI. If it is, you can call whatever code you want in Invoke
方法。
您可能还想查找其他计时器 class,具体取决于您(当前或未来)的需要。
来自MSDN:
The .NET Framework Class Library includes four classes named Timer, each of which offers different functionality:
- System.Timers.Timer, which fires an event and executes the code in one or more event sinks at regular intervals. The class is intended for use as a server-based or service component in a multithreaded environment; it has no user interface and is not visible at runtime.
- System.Threading.Timer, which executes a single callback method on a thread pool thread at regular intervals. The callback method is defined when the timer is instantiated and cannot be changed. Like the System.Timers.Timer class, this class is intended for use as a server-based or service component in a multithreaded environment; it has no user interface and is not visible at runtime.
- System.Windows.Forms.Timer, a Windows Forms component that fires an event and executes the code in one or more event sinks at regular intervals. The component has no user interface and is designed for use in a single-threaded environment.
- System.Web.UI.Timer, an ASP.NET component that performs asynchronous or synchronous web page postbacks at a regular interval.
希望对您有所帮助。
我的代码中出现上述错误。当我使用 windows 表单的计时器时,我能够成功 运行 我的应用程序。现在改成system.timers了,不知道哪里做错了。我正在实施 IMessageFilter 以收听 mouse/keyboard 移动并在有交互时重新启动计时器。如果没有交互,则隐藏表单。拜托,有人可以帮帮我吗?我正在使用 VB.Net,这是我正在使用的代码:
从表单加载
Application.AddMessageFilter(Me)
timerTest= New System.Timers.Timer()
AddHandler timerTest.Elapsed, AddressOf OnTimedTestEvent
timerTest.Enabled = True
实施 IMessageFilter
Public Function PreFilterMessage(ByRef m As Message) As Boolean Implements IMessageFilter.PreFilterMessage
If (m.Msg >= &H100 And m.Msg <= &H109) Or (m.Msg >= &H200 And m.Msg <= &H20E) Then
timerTest.Stop()
timerTest.Interval = 30000
timerTest.Start()
End If
End If
End Function
事件触发器
Private Sub OnTimedTestEvent(source As Object, e As ElapsedEventArgs)
timerTest.Stop()
HideForm()
End Sub
隐藏表格
Private Sub HideForm()
Me.Visible = False <--- getting error here
End Sub
只允许 UI 线程更改 UI 对象。这是 WinForms 的已知限制。
然而,Forms.Timer
class will keep code running in the UI's message pump, meaning you won't ever have to worry about cross-threading calls. Timers.Timer
使用自己的线程。
要获得您想要的行为,您可能需要继续使用 WinForm 的 Forms.Timer
class 或将您的 HideForm()
方法更改为:
Private Sub HideForm()
If Me.InvokeRequired Then
Me.Invoke(New Action(Sub() Me.HideForm()))
Else
Me.Visible = False
End If
End Sub
InvokeRequired
boolean property checks if the code is currently being run on another thread than the UI. If it is, you can call whatever code you want in Invoke
方法。
您可能还想查找其他计时器 class,具体取决于您(当前或未来)的需要。
来自MSDN:
The .NET Framework Class Library includes four classes named Timer, each of which offers different functionality:
- System.Timers.Timer, which fires an event and executes the code in one or more event sinks at regular intervals. The class is intended for use as a server-based or service component in a multithreaded environment; it has no user interface and is not visible at runtime.
- System.Threading.Timer, which executes a single callback method on a thread pool thread at regular intervals. The callback method is defined when the timer is instantiated and cannot be changed. Like the System.Timers.Timer class, this class is intended for use as a server-based or service component in a multithreaded environment; it has no user interface and is not visible at runtime.
- System.Windows.Forms.Timer, a Windows Forms component that fires an event and executes the code in one or more event sinks at regular intervals. The component has no user interface and is designed for use in a single-threaded environment.
- System.Web.UI.Timer, an ASP.NET component that performs asynchronous or synchronous web page postbacks at a regular interval.
希望对您有所帮助。