System.Threading.Timer fires before the interval elapsed

F

Faisal

Hi,

I'm encountering some strange problem with System.Threading.Timer. In
my application timer method is called before the interval is elapsed.
I specified 15 seconds as the interval but timer callback is called
around an interval of 14.96256.

I know that the timer is not reliable for accurate measurements. In
windows native programming I usually see the timer fires after
somtimes the interval elapsed(using the timer associated with a
window). But It's really strange that timer fires before the interval
in C#. Is this an expected behaviour.

I tested this in a sample application. Code is given below

System.Threading.Timer measImpedanceTimer;
private void button1_Click_1(object sender, EventArgs e)
{
measImpedanceTimer = new System.Threading.Timer(MeasureImpdedance,
null, 0, 15000);
}

bool bFirst = true;
DateTime testStart;
DateTime testPrev;
private void MeasureImpdedance(object step)
{
DateTime now = DateTime.Now;
if (bFirst)
{
testStart = now;
testPrev = testStart;
bFirst = false;
}

System.Diagnostics.Debug.WriteLine("Total: " + (now -
testStart).TotalSeconds +
" Diff Prev: " + (now - testPrev).TotalSeconds);
testPrev = now;
}


Output shows

Total: 0 Diff Prev: 0
Total: 14.96256 Diff Prev: 14.96256
Total: 29.92512 Diff Prev: 14.96256

Is there any way to solve this?
Also is this error-offset(15 - 14.96256) from the actual value is
consistant for all values of period?

Regards,
Faisal M
 
J

Jason Keats

Faisal said:
bool bFirst = true;
DateTime testStart;
DateTime testPrev;
private void MeasureImpdedance(object step)
{
DateTime now = DateTime.Now;
if (bFirst)
{
testStart = now;
testPrev = testStart;
bFirst = false;
}

System.Diagnostics.Debug.WriteLine("Total: " + (now -
testStart).TotalSeconds + " Diff Prev: " + (now - testPrev).TotalSeconds);
testPrev = now;
}

DateTime.Now is not a great way to time something.

You should be using System.Diagnostics.Stopwatch.
 
F

Faisal

Faisal said:
I'm encountering some strange problem with System.Threading.Timer. In
my application timer method is called before the interval is elapsed.
I specified 15 seconds as the interval but timer callback is called
around an interval of 14.96256. [...]

In addition to what Jason wrote, note that if you want a timer that has
performance characteristics closer to the WM_TIMER approach you've used
in unmanaged code, you should use System.Windows.Forms.Timer.

In this case, the measured time is repeatable and so seems more likely
to be a measurement error than a scheduling error.  But none of the
timer classes promise that they will not fire the timer event/callback
early, so even if you could measure the actual interval with 100%
accuracy, you could in fact find the timer elapsing a bit early now and
then.

The error you're seeing, 0.03744 seconds, is well within the usual ~50ms
estimate of the limits of accuracy for Windows' timing and scheduling
behavior.

Pete

Hi Pete,

Thank you for the suggestions.

In my analysis, I found that the timer will fire only at an interval
of 15.6364 milliseconds( It varies but always a value around 15ms is
found).
I think this is the minimum resolution of a timer and can't be
changed.

My actual problem is that I want to do a certain task in every 15
seconds(0 15 30 45 .....). Since the timer fires with in 14.96256
seconds, after 210secs the elapsed time becomes 209 (th error gets
added up). This is not acceptable for the application.

I don't need a resolution of milliseconds, only second resolution is
needed. But the error should not be added up to a second. is there any
way to solve this?

Regards,
Faisal M
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top