ホームページ > バックエンド開発 > 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# でのイベント処理を使用した高精度の高解像度タイマーの作成

この記事では、指定された間隔でイベントをトリガーし、標準の System.Timer クラスよりも細かい制御を提供する高解像度タイマーを C# で構築する方法について詳しく説明します。 既存の .NET オプションの制限を調査し、Windows マルチメディア タイマー API を使用した解決策を紹介します。

Stopwatch クラスは高解像度の時間測定を提供しますが、正確な間隔でイベントをトリガーするように設計されていません。 .NET Framework 自体には、私たちのニーズに直接相当するものがありません。 したがって、イベントのタイミングに合わせて最適化された 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 はリアルタイム OS ではないため、システム負荷がタイマーの精度に影響を与える可能性があることに注意してください。

結論

マルチメディア タイマー API は、C# でイベントベースのシグナリングを使用して高解像度タイマーを作成するための強力なメカニズムを提供し、正確なタイミングが重要なシナリオに対応します。 ネイティブの .NET 機能ではありませんが、その機能により、特定のタイミング要件に対する貴重なツールとなります。

以上がC# でイベントベースのインターバルシグナリングを使用した高解像度タイマーを作成するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート