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



inserted by FC2 system