I am using a System.Threading.Timer in a CF project (Windows Embedded CE 6.0), VS2005 C#, .NET 2.0.
This timer is desired because there is no possibility of reentrancy when used like this:
private System.Threading.Timer mainTimer;
private void MainForm_Load(object sender, EventArgs e)
{
// other initializations
mainTimer = new System.Threading.Timer(new TimerCallback(timerMain_Tick),
null, 100, Timeout.Infinite);
}
Which is to say, dueTime parameter is used but period is not. As long as period is Timeout.Infinite, the timer will fire once only. The timer is made thread-safe by checking for the form's InvokeRequired property. Note the check for null. It relates to my question, which I am getting to quickly.
private void timerMain_Tick(object stateInfo)
{
if (mainTimer != null)
{
if (this.InvokeRequired)
{
this.Invoke((ThreadStart)delegate
{
TimerProcess();
});
}
else
{
TimerProcess();
}
}
}
The timer must restart itself before it exits.
private void TimerProcess()
{
try
{
// do work here
}
finally
{
// retrigger
mainTimer.Change(mainTimerInterval, Timeout.Infinite);
}
}
The problem I am having is gracefully stopping this darn thing.
private void MainForm_Closing(object sender, CancelEventArgs e)
{
// shut down timer
mainTimer.Change(Timeout.Infinite, Timeout.Infinite);
mainTimer.Dispose();
mainTimer = null;
}
About 3 times in 10, the timer fires anyway, and I get an Object Disposed error. The timer code is trying to invoke the timer method AFTER the check for null.
I suspect that the timer fires, and its thread is suspended while the form is closing. I tried a state machine enumeration:
Normal state Running
Form_Closing sets Stopping state and waits in a Thread.Sleep() loop for Stopped state
Timer sees Stopping and sets Stopped state (rather than retriggering itself)
Problem I had with this is that the timer thread would not preempt the form closing method, so get stuck in endless loop.
How to fix this problem? Note that in CF, there is no Dispose(WaitHandle) method.
Best Answer
Interesting problem. There do not seem to be many options with the Timer in the Compact Framework.
I'm not sure how your specific code works, so adding a single static Boolean value may or may not fix your issues.
Here is how I changed your code to accept a
timerOK
value. If this does not solve your problem, it could give you ideas on how to approach this.