A
AMercer
The short form of this post is as follows. For an instance of
System.Timers.Timer, after setting Enabled to False, is there a foolproof way
to tell if an Elapsed event will or will not fire?
The long form follows. I have a class, MyClass, that declares
Private WithEvents MyTimer As System.Timers.Timer
Sub New for MyClass initializes MyTimer to fire Elapsed events every second.
I have an Elapsed event handler and some public methods. With SyncLock,
I've made MyClass instances thread safe. Everything works fine.
System.Timers.Timer has Close and Dispose methods, so I when I want to
destroy an instance of MyClass, I should Close or Dispose MyTimer. I've
coded MyClass.Close to look like this:
MyTimer.Enabled = False
' some cleanup I need to do
Sleep(100) ' let fire an enroute MyTimer.Elapsed
MyTimer.Dispose() ' per IDisposable
' some more cleanup I need to do
The reason for the Sleep is because of how Windows/.NET executes
MyTimer.Elapsed events. The Timer.Stop documentation says:
"The Elapsed event is raised on a ThreadPool thread, so the event-handling
method might run on one thread at the same time that a call to the Stop
method runs on another thread. This might result in the Elapsed event being
raised after the Stop method is called."
Stop and Enabled=False do the same thing. The Timer.Stop documentation goes
on to give a somewhat elaborate mechanism to overcome contention and race
conditions that might arise. My solution is Sleep(100).
I don't like my use of Sleep. I don't like the elaborate mechanism in the
documentation because it looks like it could fail if someone is messing with
thread priorities (note that the mechanism uses Sleep(0)).
So, the question is: For an instance of System.Timers.Timer, after setting
Enabled to False, is there a foolproof way to tell if an Elapsed event will
or will not fire?
System.Timers.Timer, after setting Enabled to False, is there a foolproof way
to tell if an Elapsed event will or will not fire?
The long form follows. I have a class, MyClass, that declares
Private WithEvents MyTimer As System.Timers.Timer
Sub New for MyClass initializes MyTimer to fire Elapsed events every second.
I have an Elapsed event handler and some public methods. With SyncLock,
I've made MyClass instances thread safe. Everything works fine.
System.Timers.Timer has Close and Dispose methods, so I when I want to
destroy an instance of MyClass, I should Close or Dispose MyTimer. I've
coded MyClass.Close to look like this:
MyTimer.Enabled = False
' some cleanup I need to do
Sleep(100) ' let fire an enroute MyTimer.Elapsed
MyTimer.Dispose() ' per IDisposable
' some more cleanup I need to do
The reason for the Sleep is because of how Windows/.NET executes
MyTimer.Elapsed events. The Timer.Stop documentation says:
"The Elapsed event is raised on a ThreadPool thread, so the event-handling
method might run on one thread at the same time that a call to the Stop
method runs on another thread. This might result in the Elapsed event being
raised after the Stop method is called."
Stop and Enabled=False do the same thing. The Timer.Stop documentation goes
on to give a somewhat elaborate mechanism to overcome contention and race
conditions that might arise. My solution is Sleep(100).
I don't like my use of Sleep. I don't like the elaborate mechanism in the
documentation because it looks like it could fail if someone is messing with
thread priorities (note that the mechanism uses Sleep(0)).
So, the question is: For an instance of System.Timers.Timer, after setting
Enabled to False, is there a foolproof way to tell if an Elapsed event will
or will not fire?