Home All Groups Group Topic Archive Search About

System.Threading.Timer does not tick

Author
13 Dec 2006 8:10 PM
KnighT
I have a .net service that runs a System.Threading.Timer.  The delegate
points to the function that the service should execute when the timer
elapses.  Problem: The timer is not ticking.

I have never used this timer.  I used the documentation from Microsoft
as a guide, but I cannot get this timer to work.

    Protected Overrides Sub OnStart(ByVal args() As String)
        Dim myTimer As New TimerState()

        ' Create the delegate that invokes methods for the timer.
        Dim timerDelegate As New TimerCallback(AddressOf
checkDatabases)

        ' Create a timer that waits 0 seconds, then invokes every 60
seconds.
        Dim timer As New Timer(timerDelegate, myTimer, 10000, 60000)

        log.write("Service started ")

    End Sub

The log.write("Service....") executes properly.  Why is the timer not
working ?

Author
13 Dec 2006 9:24 PM
lord.zoltar
>
>         ' Create a timer that waits 0 seconds, then invokes every 60
> seconds.
>         Dim timer As New Timer(timerDelegate, myTimer, 10000, 60000)
>

I've never created a timer this way. I usally start it explicitly
myTimer.start()
Author
14 Dec 2006 4:58 AM
Stephany Young
And as soon as the log.write("Service started ") the OnStart event handler
ends and your timer ceases to exist!!!!!!!!!

Because ... you have declared as local to the event handler!

Move it (and your state object) to class scope or higher and you should be
in business.

  Private m_timer As Timer = Nothing
  Private m_myTimer As New TimerState

  Protected Overrides Sub OnStart(ByVal args() As String)

    m_timer = New Timer(AddressOf checkDatabases, m_myTimer, 10000, 60000)

    log.write("Service started ")

  End Sub

Note also that, in VB.NET, you don't have to instantiate a delegate for the
TimerCallback. You can use AddressOf <method> directly.

Now for an anomily. Your comment says 'Create a timer that waits 0 seconds,
then invokes every 60 seconds.' but the duetime value specified in the
constructor is 10000 which indicates 10 seconds. As writ, the Timer will
'fire' after 10 seconds and then every 60 seconds after that.


Show quoteHide quote
"KnighT" <bryanjunk***@yahoo.com> wrote in message
news:1166040633.622591.166960@j72g2000cwa.googlegroups.com...
>I have a .net service that runs a System.Threading.Timer.  The delegate
> points to the function that the service should execute when the timer
> elapses.  Problem: The timer is not ticking.
>
> I have never used this timer.  I used the documentation from Microsoft
> as a guide, but I cannot get this timer to work.
>
>    Protected Overrides Sub OnStart(ByVal args() As String)
>        Dim myTimer As New TimerState()
>
>        ' Create the delegate that invokes methods for the timer.
>        Dim timerDelegate As New TimerCallback(AddressOf
> checkDatabases)
>
>        ' Create a timer that waits 0 seconds, then invokes every 60
> seconds.
>        Dim timer As New Timer(timerDelegate, myTimer, 10000, 60000)
>
>        log.write("Service started ")
>
>    End Sub
>
> The log.write("Service....") executes properly.  Why is the timer not
> working ?
>
Author
14 Dec 2006 1:46 PM
KnighT
Stephany Young wrote:
Show quoteHide quote
> And as soon as the log.write("Service started ") the OnStart event handler
> ends and your timer ceases to exist!!!!!!!!!
>
> Because ... you have declared as local to the event handler!
>
> Move it (and your state object) to class scope or higher and you should be
> in business.
>
>   Private m_timer As Timer = Nothing
>   Private m_myTimer As New TimerState
>
>   Protected Overrides Sub OnStart(ByVal args() As String)
>
>     m_timer = New Timer(AddressOf checkDatabases, m_myTimer, 10000, 60000)
>
>     log.write("Service started ")
>
>   End Sub
>
> Note also that, in VB.NET, you don't have to instantiate a delegate for the
> TimerCallback. You can use AddressOf <method> directly.
>
> Now for an anomily. Your comment says 'Create a timer that waits 0 seconds,
> then invokes every 60 seconds.' but the duetime value specified in the
> constructor is 10000 which indicates 10 seconds. As writ, the Timer will
> 'fire' after 10 seconds and then every 60 seconds after that.
>
>
> "KnighT" <bryanjunk***@yahoo.com> wrote in message
> news:1166040633.622591.166960@j72g2000cwa.googlegroups.com...
> >I have a .net service that runs a System.Threading.Timer.  The delegate
> > points to the function that the service should execute when the timer
> > elapses.  Problem: The timer is not ticking.
> >
> > I have never used this timer.  I used the documentation from Microsoft
> > as a guide, but I cannot get this timer to work.
> >
> >    Protected Overrides Sub OnStart(ByVal args() As String)
> >        Dim myTimer As New TimerState()
> >
> >        ' Create the delegate that invokes methods for the timer.
> >        Dim timerDelegate As New TimerCallback(AddressOf
> > checkDatabases)
> >
> >        ' Create a timer that waits 0 seconds, then invokes every 60
> > seconds.
> >        Dim timer As New Timer(timerDelegate, myTimer, 10000, 60000)
> >
> >        log.write("Service started ")
> >
> >    End Sub
> >
> > The log.write("Service....") executes properly.  Why is the timer not
> > working ?
> >

Thank you Stephany, I will give that a try.  That makes sense and
hopefully is the solution I am looking for.  I was just playing around
with the due time and did not change the comment.
Author
14 Dec 2006 3:18 PM
KnighT
KnighT wrote:
Show quoteHide quote
> Stephany Young wrote:
> > And as soon as the log.write("Service started ") the OnStart event handler
> > ends and your timer ceases to exist!!!!!!!!!
> >
> > Because ... you have declared as local to the event handler!
> >
> > Move it (and your state object) to class scope or higher and you should be
> > in business.
> >
> >   Private m_timer As Timer = Nothing
> >   Private m_myTimer As New TimerState
> >
> >   Protected Overrides Sub OnStart(ByVal args() As String)
> >
> >     m_timer = New Timer(AddressOf checkDatabases, m_myTimer, 10000, 60000)
> >
> >     log.write("Service started ")
> >
> >   End Sub
> >
> > Note also that, in VB.NET, you don't have to instantiate a delegate for the
> > TimerCallback. You can use AddressOf <method> directly.
> >
> > Now for an anomily. Your comment says 'Create a timer that waits 0 seconds,
> > then invokes every 60 seconds.' but the duetime value specified in the
> > constructor is 10000 which indicates 10 seconds. As writ, the Timer will
> > 'fire' after 10 seconds and then every 60 seconds after that.
> >
> >
> > "KnighT" <bryanjunk***@yahoo.com> wrote in message
> > news:1166040633.622591.166960@j72g2000cwa.googlegroups.com...
> > >I have a .net service that runs a System.Threading.Timer.  The delegate
> > > points to the function that the service should execute when the timer
> > > elapses.  Problem: The timer is not ticking.
> > >
> > > I have never used this timer.  I used the documentation from Microsoft
> > > as a guide, but I cannot get this timer to work.
> > >
> > >    Protected Overrides Sub OnStart(ByVal args() As String)
> > >        Dim myTimer As New TimerState()
> > >
> > >        ' Create the delegate that invokes methods for the timer.
> > >        Dim timerDelegate As New TimerCallback(AddressOf
> > > checkDatabases)
> > >
> > >        ' Create a timer that waits 0 seconds, then invokes every 60
> > > seconds.
> > >        Dim timer As New Timer(timerDelegate, myTimer, 10000, 60000)
> > >
> > >        log.write("Service started ")
> > >
> > >    End Sub
> > >
> > > The log.write("Service....") executes properly.  Why is the timer not
> > > working ?
> > >
>
> Thank you Stephany, I will give that a try.  That makes sense and
> hopefully is the solution I am looking for.  I was just playing around
> with the due time and did not change the comment.

This timer never works.  I created a simple windows form to test the
timer and that ticks.  The timer in my service never does what it is
supposed to do.

Even if the scope from my first post was incorrect, then it should
still call the delegate and execute the method checkDatabases AT LEAST
ONCE during the onStart().  But it never calls the delegate.  WHY ?????
Source code is supposed to do it's job.
Author
14 Dec 2006 4:18 PM
KnighT
KnighT wrote:
Show quoteHide quote
> KnighT wrote:
> > Stephany Young wrote:
> > > And as soon as the log.write("Service started ") the OnStart event handler
> > > ends and your timer ceases to exist!!!!!!!!!
> > >
> > > Because ... you have declared as local to the event handler!
> > >
> > > Move it (and your state object) to class scope or higher and you should be
> > > in business.
> > >
> > >   Private m_timer As Timer = Nothing
> > >   Private m_myTimer As New TimerState
> > >
> > >   Protected Overrides Sub OnStart(ByVal args() As String)
> > >
> > >     m_timer = New Timer(AddressOf checkDatabases, m_myTimer, 10000, 60000)
> > >
> > >     log.write("Service started ")
> > >
> > >   End Sub
> > >
> > > Note also that, in VB.NET, you don't have to instantiate a delegate for the
> > > TimerCallback. You can use AddressOf <method> directly.
> > >
> > > Now for an anomily. Your comment says 'Create a timer that waits 0 seconds,
> > > then invokes every 60 seconds.' but the duetime value specified in the
> > > constructor is 10000 which indicates 10 seconds. As writ, the Timer will
> > > 'fire' after 10 seconds and then every 60 seconds after that.
> > >
> > >
> > > "KnighT" <bryanjunk***@yahoo.com> wrote in message
> > > news:1166040633.622591.166960@j72g2000cwa.googlegroups.com...
> > > >I have a .net service that runs a System.Threading.Timer.  The delegate
> > > > points to the function that the service should execute when the timer
> > > > elapses.  Problem: The timer is not ticking.
> > > >
> > > > I have never used this timer.  I used the documentation from Microsoft
> > > > as a guide, but I cannot get this timer to work.
> > > >
> > > >    Protected Overrides Sub OnStart(ByVal args() As String)
> > > >        Dim myTimer As New TimerState()
> > > >
> > > >        ' Create the delegate that invokes methods for the timer.
> > > >        Dim timerDelegate As New TimerCallback(AddressOf
> > > > checkDatabases)
> > > >
> > > >        ' Create a timer that waits 0 seconds, then invokes every 60
> > > > seconds.
> > > >        Dim timer As New Timer(timerDelegate, myTimer, 10000, 60000)
> > > >
> > > >        log.write("Service started ")
> > > >
> > > >    End Sub
> > > >
> > > > The log.write("Service....") executes properly.  Why is the timer not
> > > > working ?
> > > >
> >
> > Thank you Stephany, I will give that a try.  That makes sense and
> > hopefully is the solution I am looking for.  I was just playing around
> > with the due time and did not change the comment.
>
> This timer never works.  I created a simple windows form to test the
> timer and that ticks.  The timer in my service never does what it is
> supposed to do.
>
> Even if the scope from my first post was incorrect, then it should
> still call the delegate and execute the method checkDatabases AT LEAST
> ONCE during the onStart().  But it never calls the delegate.  WHY ?????
>  Source code is supposed to do it's job.

Ok - I have now found part of the problem.  The method call to
checkDatabases is not calling.  So, I commented out all of the code in
the method and placed a simple log.write().  This wrote a line to the
log at every tick.  When I uncomment the code, the timer never calls
the method.

Are there restrictions or limitations to the code you are allowed to
put into this delegate ?  This just really makes no sense.  Something
in the function must be stopping the method call.  Services suck.
Author
14 Dec 2006 5:10 PM
Chris Dunaway
KnighT wrote:

> Ok - I have now found part of the problem.  The method call to
> checkDatabases is not calling.  So, I commented out all of the code in
> the method and placed a simple log.write().  This wrote a line to the
> log at every tick.  When I uncomment the code, the timer never calls
> the method.

That makes no sense at all.  Do you have exception handling in that
method?  Perhaps it is throwing an exception.  Check the Application
logs to see if it logged an exception or use try/catch to see if an
exception is occurring.
Author
15 Dec 2006 12:29 PM
Phill W.
KnighT wrote:

> Ok - I have now found part of the problem.  The method call to
> checkDatabases is not calling.  So, I commented out all of the code in
> the method and placed a simple log.write().  This wrote a line to the
> log at every tick.  When I uncomment the code, the timer never calls
> the method.

If, for any reason, the JIT compiler can't load your timer method
(missing Assemblies or methods at runtime), the timer code simply isn't
called - and there's no log of the failure anywhere that I can find!

This is one reason I /don't/ use a Timer to drive a Service, only to
start it, as in:

Sub OnStart()
    ' Use the timer to side-step the call-and-return stack, to keep
    '  the Service Control Manager happy
    tmrGo.Start()
End Sub

Sub tmrGo_Elapsed/Tick/whatever
    ' Kill the timer, which we don't need any more
    tmrGo.Stop()

    ' Run the main process
    Me.Run()

End Sub

Sub Run()
    Do While Not ShutDownRequested()
       Try

          DoWork()

       Catch ex As Exception

          LogError( ex.ToString() )

       End Try

       For i As Integer = 1 to 30
          If ShutDownRequested() Then Exit For
          System.Threading.Thread.Sleep( 1000 )
       Next
    Loop

End Sub


Are you sure

Show quoteHide quote
> Are there restrictions or limitations to the code you are allowed to
> put into this delegate ?  This just really makes no sense.  Something
> in the function must be stopping the method call.  Services suck.
>
Author
15 Dec 2006 9:50 PM
KnighT
Phill W. wrote:
Show quoteHide quote
> KnighT wrote:
>
> > Ok - I have now found part of the problem.  The method call to
> > checkDatabases is not calling.  So, I commented out all of the code in
> > the method and placed a simple log.write().  This wrote a line to the
> > log at every tick.  When I uncomment the code, the timer never calls
> > the method.
>
> If, for any reason, the JIT compiler can't load your timer method
> (missing Assemblies or methods at runtime), the timer code simply isn't
> called - and there's no log of the failure anywhere that I can find!
>
> This is one reason I /don't/ use a Timer to drive a Service, only to
> start it, as in:
>
> Sub OnStart()
>     ' Use the timer to side-step the call-and-return stack, to keep
>     '  the Service Control Manager happy
>     tmrGo.Start()
> End Sub
>
> Sub tmrGo_Elapsed/Tick/whatever
>     ' Kill the timer, which we don't need any more
>     tmrGo.Stop()
>
>     ' Run the main process
>     Me.Run()
>
> End Sub
>
> Sub Run()
>     Do While Not ShutDownRequested()
>        Try
>
>           DoWork()
>
>        Catch ex As Exception
>
>           LogError( ex.ToString() )
>
>        End Try
>
>        For i As Integer = 1 to 30
>           If ShutDownRequested() Then Exit For
>           System.Threading.Thread.Sleep( 1000 )
>        Next
>     Loop
>
> End Sub
>
>
> Are you sure
>
> > Are there restrictions or limitations to the code you are allowed to
> > put into this delegate ?  This just really makes no sense.  Something
> > in the function must be stopping the method call.  Services suck.
> >

Well I finally figured it out....almost.  The problem was that I
thought that the .exe file that .net compiled was self dependant.  So I
never put any of the .dll files that I referenced in the project.

The thing that was really throwing me off was the lack of exception
being thrown.  But I was able to see that it stopped executing the
source code at the declarations (Without throwing an exception).  It
would just stop.  After putting in the .dll files it went through the
entire method.

The second problem was correctly pointed out from the help of you guys.
This was instantiating the timer constructor in the OnStart() method.
The timer would tick once, sometimes twice, and rarely more than 4 or 5
times, then just stop.

So I put this timer in  onStart(): Dim timer As New
Timer(timerDelegate, myTimer, 10000, 0)

which calls this method:

Sub startMainTimer(ByVal state As Object)
        ' Create a timer that waits one second, then invokes every 60
seconds.
        log.write("Start main timer")
        Dim timer As New Timer(AddressOf checkDatabases, myTimer,
10000, 60000)

        ' Keep a handle to the timer
        myTimer.tmr = timer

        While (Not myTimer.tmr Is Nothing)

        End While

    End Sub

So now my timer is ticking every minute and it is properly executing
the source code in the checkDatabases() method.

New problem: lots of errors from that method, which is uploading
databases.  Which is strange because I have form that is doing the
exact same thing as the service and it works properly.

Anyways, thanks for your help.  I received some very good advice that
helped alot.