Well I've searched a lot for a solution to this. I'm looking for a clean and simple way to prevent the callback method of a System.Threading.Timer from being invoked after I've stopped it.
I can't seem to find any, and this has led me, on occassion, to resort to the dreaded thread-thread.sleep-thread.abort combo shudders.
Can it be done using lock? Please help me find a good way to do this. Thanks
For what it's worth, we use this pattern quite a bit:
To me, this seems to be the correct way to go: Just call
dispose
when you are done with the timer. That will stop the timer and prevent future scheduled calls.See example below.
This answer relates to System.Threading.Timer
I've read a lot of nonsense about how to synchronize disposal of
System.Threading.Timer
all over the net. So that's why I'm posting this in an attempt to rectify the situation somewhat. Feel free to tell me off / call me out if something I'm writing is wrong ;-)Pitfalls
In my opinion there's these pitfalls:
Timer.Dispose(WaitHandle)
can return false. It does so in case it's already been disposed (i had to look at the source code). In that case it won't set theWaitHandle
- so don't wait on it!WaitHandle
timeout. Seriously - what are you waiting for in case you're not interested in a timeout?ObjectDisposedException
can occur during (not after) disposal.Timer.Dispose(WaitHandle)
does not work properly with -Slim
waithandles, or not as one would expect. For example, the following does not work (it blocks forever):Solution
Well the title is a bit "bold" i guess, but below is my attempt to deal with the issue - a wrapper which handles double-disposal, timeouts, and
ObjectDisposedException
. It does not provide all of the methods onTimer
though - but feel free to add them.For the System.Threading.Timer one can do the following (Will also protect the callback-method from working on a disposed timer - ObjectDisposedException):
This is how one can use it:
like Conrad Frix suggested you should use the
System.Timers.Timer
class instead, like: