0

I am having the above error showing in my code. When I was using the windows form's timer, I was able to run my application successfully. Now that I have changed to system.timers, I dont know what I'm doing wrong. I am implemeting IMessageFilter to listen to mouse/keyboard movement and restarting the timer if there is interaction. If there is no interaction, hide the form. Please, can someone help me out? I am using VB.Net and here is the code I am using:

From the Form Load

Application.AddMessageFilter(Me)
timerTest= New System.Timers.Timer()
AddHandler timerTest.Elapsed, AddressOf OnTimedTestEvent
timerTest.Enabled = True

Implementing 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

Event trigger

Private Sub OnTimedTestEvent(source As Object, e As ElapsedEventArgs)

        timerTest.Stop()
        HideForm()

    End Sub

Hide the form

Private Sub HideForm()

            Me.Visible = False <--- getting error here
End Sub
Crono
  • 10,211
  • 6
  • 43
  • 75
user1884032
  • 337
  • 1
  • 5
  • 18
  • possible duplicate of [Cross-thread operation not valid: Control accessed from a thread other than the thread it was created on](http://stackoverflow.com/questions/142003/cross-thread-operation-not-valid-control-accessed-from-a-thread-other-than-the) – the_lotus Feb 24 '15 at 13:48
  • 2
    Do **not** use a System.Timers.Timer, it is a pretty nasty class and does absolutely nothing useful here. Use a System.Windows.Forms.Timer instead. Just drop one from the toolbox onto your form. – Hans Passant Feb 24 '15 at 13:48
  • @HansPassant I should use Forms.Timer instead? If I remember correctly, I thought I remember people saying how Forms.Timers could along the line of "get lost"? – user1884032 Feb 24 '15 at 13:51
  • It is pointless to fret about that, a human cannot tell that it took a few milliseconds longer to hide that window. – Hans Passant Feb 24 '15 at 14:13
  • @user1884032 Can you paste which error do you get? – kenorb Feb 24 '15 at 14:39

1 Answers1

3

Only the UI thread is allowed to change UI objects. This is a known limitation of WinForms.

The 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, however, works with its own thread.

To get the behavior you want, you may want to keep working with WinForm's Forms.Timer class or change your HideForm() method to this:

Private Sub HideForm()
    If Me.InvokeRequired Then
        Me.Invoke(New Action(Sub() Me.HideForm()))
    Else
        Me.Visible = False
    End If
End Sub

The 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 method.

You might also want to look up other timers class, depending on your (current or future) needs.

From 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.

Hope this helps.

Community
  • 1
  • 1
Crono
  • 10,211
  • 6
  • 43
  • 75