2 using System.Collections.Generic;
7 /// 一定間隔ごとの進行処理を実現するクラス。
12 /// var cf = new C定間隔進行();
13 /// cf.経過時間の分だけ進行する( 400, 定間隔処理 );
15 /// と記述した場合、400ms ごとに 定間隔処理() が実行されるようになる。
18 /// ただし、この動作は「経過時間の分だけ進行する()」メソッドを呼び出した時に、定間隔処理() を「必要な回数だけ反復実行」する仕様である。
19 /// 例えば、先述の例において、メソッドの呼び出し時点で、前回の同メソッド(またはコンストラクタ)の呼び出しから 900ms が経過していたとすると、
20 /// 定間隔処理() は 900÷400 = 2回実行され、残りの 100ms が経過時間として次回に繰り越される。
21 /// (一回の処理に時間がかかった場合にも定間隔処理が並列実行されるわけではない。)
24 /// なお、定間隔処理にラムダ式を使用する場合は、キャプチャ変数のライフサイクル(実行される時点でまだ存在しているか否か)に留意し、弱い参照 の利用も検討すること。
30 /// コンストラクタ。初期化と同時に、間隔の計測も開始する。
36 public void 経過時間の計測を開始する()
43 public void 経過時間の計測を一時停止する()
50 public void 経過時間の計測を再開する()
57 public void 経過時間の分だけ進行する( long 間隔ms, Action 定間隔処理 )
62 this.Timer.現在のカウントをキャプチャする();
63 long 現在時刻ms = this.Timer.現在のキャプチャカウント100ns単位 / 10000;
65 // 初めての進行の場合、前回時刻を初期化する。
66 if( QPCTimer.未使用 == this.前回の進行時刻ms )
68 this.前回の進行時刻ms = 現在時刻ms;
71 // (ないと思うが)タイマが一回りしてしまった時のための保護。正常動作を保証するものではない。
72 if( 現在時刻ms < this.前回の進行時刻ms )
74 this.前回の進行時刻ms = 現在時刻ms;
77 // 経過時間における回数だけ、処理を実行する。
78 while( ( 現在時刻ms - this.前回の進行時刻ms ) >= 間隔ms )
81 this.前回の進行時刻ms += 間隔ms;
86 private long 前回の進行時刻ms = QPCTimer.未使用;
87 private readonly QPCTimer Timer = new QPCTimer();
88 private readonly object 排他利用 = new object();