This article details building a high-resolution timer in C# that triggers an event at specified intervals, offering finer control than the standard System.Timer
class. We'll explore the limitations of existing .NET options and present a solution using the Windows Multimedia Timer API.
While the Stopwatch
class provides high-resolution time measurement, it's not designed for event triggering at precise intervals. The .NET framework itself lacks a direct equivalent to our needs. Therefore, we'll leverage the Windows Multimedia Timer API, which is optimized for event timing.
Below is a C# implementation utilizing the Multimedia Timer API:
<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>
Important Considerations:
The Multimedia Timer API interacts with system-wide settings; adjustments could affect system performance. Monitor timer frequency to ensure it matches the target interval. Remember that Windows isn't a real-time OS, so system load might impact timer accuracy.
The Multimedia Timer API provides a powerful mechanism for creating high-resolution timers with event-based signaling in C#, addressing scenarios where precise timing is critical. While not a native .NET feature, its capabilities make it a valuable tool for specific timing requirements.
The above is the detailed content of How Can I Create a High-Resolution Timer with Event-Based Interval Signaling in C#?. For more information, please follow other related articles on the PHP Chinese website!