VB.NET.
Trying to make a Sub Main
behave like a form. In the sense that it doesn't consume the processor and Sub Main
keeps running indefinitely, with a Timer Event that will fire approx once per second.
The code below gives me the behavior I want but I don't fully understand how the EventWaitHandle
works. My question is... Does anyone know if this is a good approach or if there might be an easier way to just have a Sub Main that basically doesn't do anything but allow a Timer event to fire?
Imports System.Threading
Module MainMod
Public Sub Main(args As String())
Dim waitHandle = New System.Threading.EventWaitHandle(True, EventResetMode.AutoReset, "", False)
Dim timer = New Timer(AddressOf OnTimerElapsed, Nothing, TimeSpan.Zero, TimeSpan.FromSeconds(1))
Do While True
waitHandle.WaitOne(TimeSpan.FromSeconds(20))
Loop
End Sub
Private Sub OnTimerElapsed(state As Object)
Debug.WriteLine(DateAndTime.Now.ToString)
End Sub
End Module
EventWaitHandle
in your code is really not doing anything special. It is simply allowing you to wait infinitely. However, this is not the standard use for EventWaitHandle
. EventWaitHandle
is used generally to synchronize between different threads. It allows one thread to wait for another thread to signal that something happened.
It doesn't seem to me that you need this functionality, you simply need to wait.
You can simply call Console.ReadLine
. This will cause the main thread to wait, but will cause the application to exit if the user inputs a line.
Another way is to use Thread.Sleep
which will cause the main thread to wait also. Putting that in a loop will cause the main thread to wait indefinitely.
Consider the following code:
Public Sub Main(args As String())
Dim timer = New Timer(AddressOf OnTimerElapsed, Nothing, TimeSpan.Zero, TimeSpan.FromSeconds(1))
Do While True
Thread.Sleep(TimeSpan.FromSeconds(20))
Loop
End Sub
Private Sub OnTimerElapsed(state As Object)
Debug.WriteLine(DateAndTime.Now.ToString)
End Sub
Another comment about your code is that using the System.Threading.Timer
class will cause the OnTimerElapsed
to be called a second time while the first call is not finished if the first call is taking more that one second (the timer period value) to complete.
This means that the Timer does not wait for the previous invocation to complete before issuing a new one.
If this is the behavior that you want, then it is fine.
If not, then you can replace your application with a simple loop and use Thread.Sleep
like this:
Public Sub Main(args As String())
Do While True
Thread.Sleep(TimeSpan.FromSeconds(1))
OnTimerElapsed()
Loop
End Sub
Private Sub OnTimerElapsed()
Debug.WriteLine(DateAndTime.Now.ToString)
End Sub