C#, ロジック
- マルチメディアタイマー
C#でマルチメディアタイマーを使用する方法を説明します。WindowsではSleepの精度は時刻精度はデフォルトで10msと言われており、それより高精度にタイムスタンプを刻みたければ、特殊なAPIを使用する必要があります。timeBeginPeriodメソッドにより最高1msまで精度を高めることが可能です。
ただし、タイマーの精度はOS単位に決まってしまうことに注意が必要です。ひとつのアプリケーションの精度を上げてしまうと、そのOS上で動いている全てのアプリケーションでも同じ精度に設定されます。タイマーの精度を変えることによって誤動作するアプリケーションも存在します。アプリケーション終了時にtimeEndPeriodでもとの10msに戻しておくことをお勧めします。
public class MultimediaTimer
{
/// <summary>起動チックカウント</summary>
private uint _nTickCountStart;
/// <summary>起動時刻</summary>
private DateTime _timeStart;
/// <summary>サンプリング実行用スレッド</summary>
private Thread _thread;
public MultimediaTimer()
{
timeBeginPeriod( 1 );
}
public void Start()
{
_timeStart = DateTime.Now;
_nTickCountStart = timeGetTime();
_thread = new Thread( SamplingLoopThread );
_thread.Start();
}
public void End()
{
if( _thread != null )
{
_thread.Abort();
_thread = null;
}
timeEndPeriod( 10 );
}
private void SamplingLoopThread()
{
while( true )
{
// Start()から数えた時刻取得
uint unDev = timeGetTime() - _nTickCountStart;
DateTime time = _timeStart + new TimeSpan( 0, 0, 0, 0, ( int )unDev );
// トレース
System.Diagnostics.Trace.WriteLine( "TickTime " + time.ToString( "yyyy/MM/dd HH:mm:ss:fff" ) );
// 10msインターバル
Thread.Sleep( 10 );
}
}
[DllImport( "winmm.dll", EntryPoint = "timeBeginPeriod" )]
public static extern uint timeBeginPeriod( uint uMilliseconds );
[DllImport( "winmm.dll", EntryPoint = "timeEndPeriod" )]
public static extern uint timeEndPeriod( uint uMilliseconds );
[DllImport( "winmm.dll", EntryPoint = "timeGetTime" )]
public static extern uint timeGetTime();
}
結果
timeBeginPeriod( 1 );を入れたとき(インターバルに1ms程度の誤差があります。)
TickTime 2008-09-26 15:21:13:536
TickTime 2008-09-26 15:21:13:546
TickTime 2008-09-26 15:21:13:557
TickTime 2008-09-26 15:21:13:568
TickTime 2008-09-26 15:21:13:578
TickTime 2008-09-26 15:21:13:589
TickTime 2008-09-26 15:21:13:600
TickTime 2008-09-26 15:21:13:611
TickTime 2008-09-26 15:21:13:621
TickTime 2008-09-26 15:21:13:632
timeBeginPeriod( 1 );を入れないとき(インターバルに6ms程度の誤差があります。)
TickTime 2008-09-26 15:19:29:452
TickTime 2008-09-26 15:19:29:468
TickTime 2008-09-26 15:19:29:484
TickTime 2008-09-26 15:19:29:499
TickTime 2008-09-26 15:19:29:515
TickTime 2008-09-26 15:19:29:530
TickTime 2008-09-26 15:19:29:546
TickTime 2008-09-26 15:19:29:562
TickTime 2008-09-26 15:19:29:577