C#中的高分辨率计时器

C#中的高分辨率计时器,第1张

C#中的高分辨率计时器

我所知道的没有内置到.NET框架中。Windows具有通过Multimedia Timer
API
进行高分辨率计时器事件的机制。下面是一个简单的例子,我似乎可以解决。也有似乎是一个很好的例子在这里。

我将注意,此API会更改系统范围的设置,从而降低系统性能,因此请买家注意。为了进行测试,我建议您跟踪计时器触发的频率,以验证时序是否与您要模拟的设备相似。由于Windows不是实时 *** 作系统,因此系统上的负载可能会导致MM计时器延迟,从而导致100毫秒的间隔,其中包含100个连续快速的事件,而不是间隔1毫秒的100个事件。有关MM计时器的一些其他资料。

class Program{    static void Main(string[] args)    {        TestThreadingTimer();        TestMultimediaTimer();    }    private static void TestMultimediaTimer()    {        Stopwatch s = new Stopwatch();        using (var timer = new MultimediaTimer() { Interval = 1 })        { timer.Elapsed += (o, e) => Console.WriteLine(s.ElapsedMilliseconds); s.Start(); timer.Start(); Console.ReadKey(); timer.Stop();        }    }    private static void TestThreadingTimer()    {        Stopwatch s = new Stopwatch();        using (var timer = new Timer(o => Console.WriteLine(s.ElapsedMilliseconds), null, 0, 1))        { s.Start(); Console.ReadKey();        }    }}public class MultimediaTimer : IDisposable{    private bool disposed = false;    private int interval, resolution;    private UInt32 timerId;    // Hold the timer callback to prevent garbage collection.    private readonly MultimediaTimerCallback Callback;    public MultimediaTimer()    {        Callback = new MultimediaTimerCallback(TimerCallbackMethod);        Resolution = 5;        Interval = 10;    }    ~MultimediaTimer()    {        Dispose(false);    }    public int Interval    {        get        { return interval;        }        set        { CheckDisposed(); if (value < 0)     throw new ArgumentOutOfRangeException("value"); interval = value; if (Resolution > Interval)     Resolution = value;        }    }    // Note minimum resolution is 0, meaning highest possible resolution.    public int Resolution    {        get        { return resolution;        }        set        { CheckDisposed(); if (value < 0)     throw new ArgumentOutOfRangeException("value"); resolution = value;        }    }    public bool IsRunning    {        get { return timerId != 0; }    }    public void Start()    {        CheckDisposed();        if (IsRunning) throw new InvalidOperationException("Timer is already running");        // Event type = 0, one off event        // Event type = 1, periodic event        UInt32 userCtx = 0;        timerId = NativeMethods.TimeSetEvent((uint)Interval, (uint)Resolution, Callback, ref userCtx, 1);        if (timerId == 0)        { int error = Marshal.GetLastWin32Error(); throw new Win32Exception(error);        }    }    public void Stop()    {        CheckDisposed();        if (!IsRunning) throw new InvalidOperationException("Timer has not been started");        StopInternal();    }    private void StopInternal()    {        NativeMethods.TimeKillEvent(timerId);        timerId = 0;    }    public event EventHandler Elapsed;    public void Dispose()    {        Dispose(true);    }    private void TimerCallbackMethod(uint id, uint msg, ref uint userCtx, uint rsv1, uint rsv2)    {        var handler = Elapsed;        if (handler != null)        { handler(this, EventArgs.Empty);        }    }    private void CheckDisposed()    {        if (disposed) throw new ObjectDisposedException("MultimediaTimer");    }    private void Dispose(bool disposing)    {        if (disposed) return;        disposed = true;        if (IsRunning)        { StopInternal();        }        if (disposing)        { Elapsed = null; GC.SuppressFinalize(this);        }    }}internal delegate void MultimediaTimerCallback(UInt32 id, UInt32 msg, ref UInt32 userCtx, UInt32 rsv1, UInt32 rsv2);internal static class NativeMethods{    [Dllimport("winmm.dll", SetLastError = true, EntryPoint = "timeSetEvent")]    internal static extern UInt32 TimeSetEvent(UInt32 msDelay, UInt32 msResolution, MultimediaTimerCallback callback, ref UInt32 userCtx, UInt32 eventType);    [Dllimport("winmm.dll", SetLastError = true, EntryPoint = "timeKillEvent")]    internal static extern void TimeKillEvent(UInt32 uTimerId);}


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5487525.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-12
下一篇 2022-12-12

发表评论

登录后才能评论

评论列表(0条)

保存