首页 > 后端开发 > C++ > 如何在 C# 中创建具有基于事件的间隔信号的高分辨率计时器?

如何在 C# 中创建具有基于事件的间隔信号的高分辨率计时器?

Susan Sarandon
发布: 2025-01-17 10:51:10
原创
548 人浏览过

How Can I Create a High-Resolution Timer with Event-Based Interval Signaling in C#?

使用 C# 中的事件处理创建精确的高分辨率计时器

本文详细介绍了如何用 C# 构建一个高分辨率计时器,该计时器以指定的时间间隔触发事件,从而提供比标准 System.Timer 类更精细的控制。 我们将探索现有 .NET 选项的局限性,并使用 Windows 多媒体计时器 API 提出解决方案。

虽然 Stopwatch 类提供高分辨率时间测量,但它并不是为以精确间隔触发事件而设计的。 .NET 框架本身缺乏直接满足我们需求的框架。 因此,我们将利用针对事件计时进行了优化的 Windows 多媒体计时器 API。

使用多媒体计时器 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 不是实时操作系统,因此系统负载可能会影响计时器的准确性。

结论

多媒体计时器 API 提供了一种强大的机制,用于在 C# 中使用基于事件的信号创建高分辨率计时器,解决精确计时至关重要的场景。 虽然不是本机 .NET 功能,但其功能使其成为满足特定计时要求的宝贵工具。

以上是如何在 C# 中创建具有基于事件的间隔信号的高分辨率计时器?的详细内容。更多信息请关注PHP中文网其他相关文章!

来源:php.cn
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
作者最新文章
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板