I am using a LargeIntervalTimer from OpenNetCF to do polling when on a particular screen in certain conditions.
As I don't want the timer firing constantly I try to dispose of it once it's no longer needed, however calling Dispose() or setting Enabled to false in the UI thread will often hang the application.
I have tried moving the timer disposal code onto the timer's thread (by calling it in the tick method) and this just makes the hang more consistent, (albeit in a separate thread so the rest of the app keeps working).
Has anyone seen similar issues with this timer, and if so how did you fix them?
Code for start up:
_timer = new LargeIntervalTimer();
_timer.OneShot = false;
_timer.Tick += TimerTick;
_timer.Interval = new TimeSpan(0, 0, 30);
_timer.FirstEventTime = DateTime.Now.AddSeconds(30);
_timer.Enabled = true;
Code for shutdown:
if (_timer != null)
{
_timer.Enabled = false;
_timer.Dispose();
_timer = null;
}
Looking at the LIT source, I'm not seeing any reason why Disposing it would cause any issue. Dispose looks like this:
As you can see, it sets Enabled to
false
and then sets aWaitHandle
.The Enabled implementation is similarly simple:
Basically if we're disabling and we were enabled, the same WaitHandle that Dispose will be setting is getting set. Redundant, yes, but not a problem. SetEvent is not a clocking call, so this code is all that happens as a direct result of your call and should be the only thing that would affect a "hang" scenario. But for completeness, let's look at what this event is triggering. Here's teh worker thread proc (which is largely the meat of the LIT class):
About half way in you'll see a
source = WaitAny
call, which is where that event is caught. It simply returns1
when the event from the above snipptes is called, which drops us to theelse
which sets m_enabled to false, which then exits the while loop and runs the finally block. The finally block resets the waithandle is all threads have exited and you're done. Again, pretty simple, and I see no potentials for a hang.At this point all I can recommend is putting
Debug.Writeline
calls into the LIT source to see what's happening in your use case. It might shed a little more light on what's happening in your environment to cause bad behavior.Bear in mind that Disposing the LIT still may leave a single notification active in your OS notifications queue, so the event registered is still going to fire one more time. That still should have zero impact, as we're no longer listening for it so it's just going to fire with no listeners, which is not a problem.