我的代码中显示上述错误。当我使用Windows窗体的计时器时,我能够成功运行我的应用程序。现在我已经改为system.timers,我不知道我做错了什么。我正在实现IMessageFilter来监听鼠标/键盘移动并在有交互时重新启动计时器。如果没有交互,请隐藏表单。拜托,有人可以帮帮我吗?我正在使用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
答案 0 :(得分:1)
只允许UI线程更改UI对象。这是WinForms的一个已知限制。
Forms.Timer
课程将在UI的消息泵中保持代码运行,这意味着您不必担心跨线程调用。但是,Timers.Timer
可以使用自己的主题。
要获得所需的行为,您可能希望继续使用WinForm的Forms.Timer
课程或将HideForm()
方法更改为:
Private Sub HideForm()
If Me.InvokeRequired Then
Me.Invoke(New Action(Sub() Me.HideForm()))
Else
Me.Visible = False
End If
End Sub
InvokeRequired
布尔属性检查代码当前是否在除UI之外的其他线程上运行。如果是,您可以在Invoke
方法中调用您想要的任何代码。
您可能还想查找其他计时器课程,具体取决于您(当前或将来)的需求。
来自MSDN:
.NET Framework类库包含四个名为Timer的类,每个类都提供不同的功能:
- System.Timers.Timer ,它会定期触发事件并在一个或多个事件接收器中执行代码。该类旨在用作多线程环境中的基于服务器或服务组件;它没有用户界面,在运行时不可见。
- System.Threading.Timer ,它定期在线程池线程上执行单个回调方法。回调方法是在实例化定时器时定义的,无法更改。与System.Timers.Timer类一样,此类旨在用作多线程环境中的基于服务器或服务组件;它没有用户界面,在运行时不可见。
- System.Windows.Forms.Timer ,一个Windows窗体组件,用于触发事件并定期在一个或多个事件接收器中执行代码。该组件没有用户界面,专为在单线程环境中使用而设计。
- System.Web.UI.Timer ,一个定期执行异步或同步网页回发的ASP.NET组件。
希望这有帮助。