private: System::Windows::Forms::Timer^ timer1;
...
this->timer1->Interval = 10;
this->timer1->Tick += gcnew System::EventHandler(this, &Form1::timer1_Tick);
...
intCentiSeconds= 0;
intSeconds = 0;
intMinutes = 0;
intHours = 0;
...
private: System::Void timer1_Tick(System::Object^ sender, System::EventArgs^ e) {
intCentiSeconds++;
if(intCentiSeconds==100){
intCentiSeconds = 0;
intSeconds++;
}
if(intSeconds==60){
intSeconds = 0;
intMinutes++;
}
if(intMinutes==60){
intMinutes = 0;
intHours++;
}
...
直到昨天我试图用它来检查我的心率时,还没有付出任何心思,并且惊讶地看到它有多高。经过一番摸索,弄清楚为什么我的心脏异常快,我最后测试了我的“秒表”对着Windows的时钟和我的手机的秒表,结果证明上面的代码导致一个非常慢的计时器:数到1分钟在大约1'30“。
经过一番挖掘后,我发现了
Windows窗体计时器组件是单线程的,并且仅限于 精度为55毫秒
我认为我得到了答案,所以我想我可以使用十分之一秒的时间(this->timer1->Interval = 10;
)并重新编译。准确度提高了,但仍然很慢。最后,我摆脱了所有的亚秒级测量,并且精度再次提高,但是它在5分钟内仍然是5秒钟。
使用像System :: Timers :: Timer这样更精确的计时器可能会解决这个问题,但我并不特别关心这个秒表,它只是一个学习项目。
我想要的是解释这里发生的事情。为什么假设准确度为55ms的定时器在1000 ms间隔内仍然明显不准确?
答案 0 :(得分:0)
这可能是由于事件处理产生的开销。
定时器每次滴答时都会引发一个事件。 UI线程识别并处理此事件需要一些时间。此外,如果UI线程被其他任务占用,则可能无法立即识别此事件。特别是,如果这个开销大约是或大于滴答间隔本身的顺序,那么你就会遇到问题。
由于每次发生Tick事件时都会产生的开销,如果没有正确考虑,则不准确性会随着时间的推移而变得复杂。