Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
320 views
in Technique[技术] by (71.8m points)

c# - How to make an accurate decimal Timer?

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 ..

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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();
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...