Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / .NET Framework / New Users / March 2008

Tip: Looking for answers? Try searching our database.

System.Timers.Timer and Close/Dispose

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
AMercer - 12 Mar 2008 16:18 GMT
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?
Peter Duniho - 12 Mar 2008 19:01 GMT
> [...]
> 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)).

The mechanism shown in that sample looks reliable to me, as far as it  
goes.  They aren't using Sleep() as part of the synchronization...they're  
just putting it there to ensure that the "control" thread doesn't chew up  
the CPU while trying to take control of the status variable (and they use  
Sleep(1), not Sleep(0)...there's a significant difference between the two).

Personally, I don't like that example very much, mainly because it is so  
complicated.  It's complicated because they wanted to demonstrate  
something a little more elaborate than just stopping the timer.  They  
could have dealt with a race condition just by setting a volatile boolean  
variable that signals to the timer event handler that the timer's been  
stopped and so shouldn't do any work.  But in the example they also want  
to _know_ whether the timer was simply stopped or if it had to rely on  
that flag to stop processing, so that the behavior could be reported back  
later.

In doing so, they want a variable that they look at and then set according  
to the current value, and the easiest reliable way to do that is with  
Interlocked.CompareExchange().  If it wasn't for that need, they could've  
just set a flag.

> 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?

That depends on your definition of "after".  I believe that the Timer  
class is reliable in the sense that if you disable the timer, then _after_  
that point the timer event won't be raised.  The problem comes in that the  
timer event may already have started to be raised by the time you disable  
the timer, and yet it might not have completely executed by that point.

So you can still get code handling the timer executing after you've  
disabled the timer.

The fact is, even the code sample you've seen on MSDN doesn't really  
address that issue per se.  After all, the handler could still already be  
executing past the point at which is actually attempts to check the status  
variable they're using.  Even in that example, it's still possible to have  
timer handler code execute after disabling the timer.

What that code sample does address is the ability for information to flow  
in both directions, so that the control thread can be sure that by the  
time it gets past that while loop, the timer event handler is done  
working.  It's only necessary to do this (or something like it) if you  
have code in the thread modifying the timer that needs to be mutually  
exclusive with code in the timer event handler itself.  And the sample  
clearly states this in the comments, by the way.

So this brings us back to your question: if by "fire" you mean that you  
may have event handler code executing after you stop the timer,  
no...there's no way to tell if that will happen.  You can be assured that  
the event itself won't be raised after you disable the timer, but if it's  
already been raised before you do that, the best you can do is determine  
whether the event handler code is executing and act accordingly.

Now, you mentioned that you want to call Dispose().  You don't say so  
explicitly, but there seems to be an implication in your post that this is  
the reason you want to synchronize access to the timer's event handler.  
If so, then I don't think this is a concern.  I prefer the Threading.Timer  
or Forms.Timer timers and so don't have a lot of first-hand experience  
with the Timers.Timer, but my understanding is that there's no problem if  
you call Dispose() or Close() on the timer while the event handler is  
executing.  I believe that the timer just queues the method that raises  
the event on the ThreadPool thread, and that's not something that once  
started should be affected by a call to dispose the timer object itself.

Pete
AMercer - 12 Mar 2008 20:07 GMT
Thanks for your thoughtful reply.  My concern all along was about disposing
the timer while there was an Elapsed event pending.  By pending I mean that
the event has been raised but my handler hasn't yet been called.  I was
worried about something going wrong with the timer after it had been
disposed.  The 'something' would likely be an extremely rare unhandled
exception of some undetermined type, and I wanted to take steps to prevent
that.

Also, I'll take a look at Threading.Timer.  My investment in Timers.Timer
isn't much.  I can't use Forms.Timer for my problem.

> > [...]
> > I don't like my use of Sleep.  I don't like the elaborate mechanism in  
[quoted text clipped - 72 lines]
>
> Pete

Rate this thread:







Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.