0

数年前、次のコードを使用して、学習プロジェクトとして小さなストップウォッチを作成しました。

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;) に 10 分の 1 秒を使用して再コンパイルできると考えました。精度は向上しましたが、それでもかなり遅かったです。最後に、すべてのサブ秒単位の測定値を取り除き、再び精度が向上しましたが、それでも 5 分間で 5 秒ずれています。

System::Timers::Timer のようなより正確なタイマーを使用すると、おそらく問題が解決するでしょうが、私はこのストップウォッチについて特に気にしません。それは昔からの学習プロジェクトでした。

私が欲しいのは、ここで何が起こっているかの説明です。タイマーが 55 ミリ秒で正確であると想定されているのに、1000 ミリ秒間隔ではまだ著しく不正確なのはなぜですか?

4

1 に答える 1

0

これは、イベント処理によるオーバーヘッドが原因である可能性があります。

タイマーは、刻むたびにイベントを発生させます。このイベントが UI スレッドによって認識され、処理されるまでには時間がかかります。また、UI スレッドが他のタスクで占有されている場合、このイベントはすぐには認識されない場合があります。特に、このオーバーヘッドがティック間隔自体と同程度かそれより大きい場合、問題が発生します。

このオーバーヘッドはTick イベントが発生するたびに発生するため、適切に考慮されていないと、時間の経過とともに不正確さが悪化します。

于 2013-10-25T07:53:40.750 に答える