Any ideas on what could be causing the System.Timers.Timer.set_Enabled property to throw a System.NullReferenceException?

Here is the stack trace:

2012-03-16 19: 15: 09Z E System.NullReferenceException: Object reference not set to object instance.
   at System.Timers.Timer.set_Enabled (boolean)
   at System.Timers.Timer.Stop ()

Here's the code:

The timer is declared as a private member variable.

Private _myTimer As System.Timers.Timer

      

Initialize timer method.

Private Sub InitializeMyTimer()

    _myTimer = New System.Timers.Timer

    _myTimer.Interval = My.Settings.TimeoutSeconds * 1000
    _myTimer.Start()

    AddHandler _myTimer.Elapsed, AddressOf MyTimer_Elapsed

End Sub

      

Elapsed timer. WsMethodAsync calls the .asmx web service method.

Private Sub MyTimer_Elapsed(ByVal sender As Object, ByVal e As     System.Timers.ElapsedEventArgs)

    Try

        _myTimer.Stop()

        Using thisWSHelper As New WSHelper

            thisWsHelp.WsMethodAsync()

        End Using

        _myTimer.Start()

    Catch ex As Exception

      LogAndShowException(ex)

    End Try

End Sub

      

The timer must be set, otherwise Timer.Stop () will throw an exception. This is a sporadic error and I'm just trying to figure out if anyone has experienced this before, or if anyone has any ideas on what might be causing this. This happens in a WinForms application in an event handler for a past timer event, but it only happens intermittently on the user's computer. I myself have not been able to reproduce the error.

+3


source to share


2 answers


Well, let's say you figured out that the System.Timers.Timer class implements IDisposable and that you've written code to properly dispose of the timer the way you should:

Private Sub OnDisposed(ByVal sender As Object, ByVal e As EventArgs) Handles MyBase.Disposed
    If myTimer IsNot Nothing Then
        myTimer.Dispose()
        myTimer = Nothing
    End If
End Sub

      



Yes, it will be kaboom from time to time. The Elapsed event is raised by a thread pool thread and can fire at any odd time. This can take a few seconds if the threadpool is particularly busy. Eliminating the timer does not prevent the event from firing, the tp stream is already in flight. So with this particular code, it is very likely that you will get an NRE. It's just that sometimes, never when you are debugging code.

Stopping control of System.Timers.Timer is quite difficult, you can never be sure that the Elapsed event will not fire after you have disabled it. Write defensively and keep in mind that this is possible. And the benefit of System.Threading.Timer.

+2


source


First, the reason you are seeing these random exceptions:

A is System.Timers.Timer

used as System.Threading.Timer and as Hans Passant said, each iteration is done on a different thread. This allows your event Elapsed

to be raised after the timer has been disabled, because a new iteration can be started before the previous one is executed.

The way it works System.Timers.Timer

is disabling it, it provides a base one System.Threading.Timer

and sets it to Nothing. In a rare (is this word redundant?) Race condition, your timer will try to start Dispose

on its base timer while it is set to Nothing, resulting in NullReferenceException

.




One solution would be to set the property Timer.AutoReset

to False and restart the timer on your event Elapsed

.

+1


source







All Articles