使用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.

希望对您有所帮助。