I'm pretty frustrated about this one ..
I have a timer called timer1
and a text box called TimeElapsedTextBox
and a double
variable called TimeTakenToFinish
the timer ticks every 1 second (1000 millisecond)
in the text box, I want it to display the time in this format:
Seconds.PartsOfSecond
Here is the Tick event:
private void timer1_Tick(object sender, EventArgs e)
{
TimeTakenToFinish += (double)timer1.Interval / 10000;
TimeElapsedTextBox.Text = TimeTakenToFinish;
}
it is actually displaying it in the text box the way i want it,
but it's not counting properly ..
I mean, it's counting less than a real second..
could you please tell me how to fix this ..
Your problem here is a misunderstanding of the way your OS works. Sure, you can set the interval to 1000ms
, but you cannot expect it to actually tick every second. You are running code on Windows, not a hard (or soft) real time operating system.
As an aside, you should also know that the resolution of your timer is finite, and as of today, limited to the accuracy of your system timer, which is probably about 15ms.
You cannot expect your code to perform that deterministically in that sort of environment. At any point the OS can preemptively kick you out of the CPU and start working on another task.
You simply cannot get the accuracy you desire, though I would ask; is it actually required? Probably not, but you haven't told us what you are actually trying to accomplish here, so who knows?
Also, this is wrong:
TimeTakenToFinish += (double)timer1.Interval / 10000;
Interval
is a property which is used to tell the timer roughly how often it should fire the Tick
event. You are not actually measuring anything, you may as well just be adding 1000.0 / 10000
to your counter every time.
If you need more precision use the StopWatch
class which uses your CPU's high performance timer if available. You can still use a timer to periodically update the UI based on the current elapsed value of the Stopwatch, i.e.,
void timer1_Tick(...)
{
var totalSeconds = _someStopwatch.ElapsedMilliseconds / 1000.0;
TimeElapsedTextBox.Text = totalSeconds.ToString();
}
Instead of using a timer, record the start time using DateTime.Now and then subtract the current time (DateTime.Now) from the start time. This will give you a more accurate timer as it uses the system clock instead which isn't affected so much by CPU performance.
Alternatively you can use System.Diagnostics.Stopwatch which does this for you.
You can still use an ordinary timer with an interval of less than a second to refresh the label displaying the time.