この記事では、指定された間隔でイベントをトリガーし、標準の System.Timer
クラスよりも細かい制御を提供する高解像度タイマーを C# で構築する方法について詳しく説明します。 既存の .NET オプションの制限を調査し、Windows マルチメディア タイマー API を使用した解決策を紹介します。
Stopwatch
クラスは高解像度の時間測定を提供しますが、正確な間隔でイベントをトリガーするように設計されていません。 .NET Framework 自体には、私たちのニーズに直接相当するものがありません。 したがって、イベントのタイミングに合わせて最適化された Windows マルチメディア タイマー API を活用します。
以下は、マルチメディア タイマー API を利用した C# 実装です。
<code class="language-csharp">using System; using System.Runtime.InteropServices; class MultimediaTimer : IDisposable { private bool disposed = false; private int interval, resolution; private uint timerId; private readonly MultimediaTimerCallback Callback; public delegate void MultimediaTimerCallback(uint uTimerID, uint uMsg, IntPtr dwUser, uint dw1, uint dw2); public event EventHandler<EventArgs> TimerElapsed; public MultimediaTimer() { Callback = new MultimediaTimerCallback(TimerCallbackMethod); Resolution = 5; // Default resolution (milliseconds) Interval = 10; // Default interval (milliseconds) } ~MultimediaTimer() { Dispose(false); } public int Interval { get { return interval; } set { CheckDisposed(); if (value > 0) interval = value; } } public int Resolution { get { return resolution; } set { CheckDisposed(); if (value > 0 && value <= interval) resolution = value; } } public void Start() { CheckDisposed(); uint result = timeSetEvent((uint)interval, (uint)resolution, Callback, IntPtr.Zero, 1); if (result == 0) throw new Exception("Failed to start timer."); timerId = result; } public void Stop() { CheckDisposed(); if (timerId != 0) timeKillEvent(timerId); timerId = 0; } private void TimerCallbackMethod(uint uTimerID, uint uMsg, IntPtr dwUser, uint dw1, uint dw2) { TimerElapsed?.Invoke(this, EventArgs.Empty); } private void CheckDisposed() { if (disposed) throw new ObjectDisposedException("MultimediaTimer"); } protected virtual void Dispose(bool disposing) { if (!disposed) { Stop(); disposed = true; } } public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } [DllImport("winmm.dll")] private static extern uint timeSetEvent(uint uDelay, uint uResolution, MultimediaTimerCallback lpTimeProc, IntPtr dwUser, uint fuEvent); [DllImport("winmm.dll")] private static extern uint timeKillEvent(uint uTimerID); }</code>
重要な考慮事項:
マルチメディア タイマー API はシステム全体の設定と対話します。調整するとシステムのパフォーマンスに影響を与える可能性があります。 タイマーの頻度を監視して、目標の間隔と一致していることを確認します。 Windows はリアルタイム OS ではないため、システム負荷がタイマーの精度に影響を与える可能性があることに注意してください。
マルチメディア タイマー API は、C# でイベントベースのシグナリングを使用して高解像度タイマーを作成するための強力なメカニズムを提供し、正確なタイミングが重要なシナリオに対応します。 ネイティブの .NET 機能ではありませんが、その機能により、特定のタイミング要件に対する貴重なツールとなります。
以上がC# でイベントベースのインターバルシグナリングを使用した高解像度タイマーを作成するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。