Timerクラス

System.Threading.Timerクラスは、内部ではThreadPool.UnsafeQueueUserWorkItem()でスレッドが実行されます。QueueTimerCompletion - timer.cs

同名のTimerクラス

.NET Frameworkにはこれと同名のTimerクラスが4つあるため、名前空間に注意します。

注釈 - Timer クラス (System.Timers) | Microsoft Learn

Visual Studioのタイマー

Visual StudioのデザイナにあるタイマーはSystem.Windows.Forms.Timerであり、ここで解説するSystem.Threading.Timerとは異なります。このクラスはすべての処理を1つのスレッドで行うため、複数のタイマを同時に実行できません。


Visual Studioのツールボックス

コンストラクタ

public Timer(
    TimerCallback callback,  // 実行するコールバック メソッド
    Object state,            // callbackへ渡すデータ
    int dueTime,             // callbackが呼び出されるまでの遅延時間 [msec]
    int period               // callbackが呼び出される周期 [msec]
    )
Timer(TimerCallback, Object, Int32, Int32) - Timer コンストラクター (System.Threading) | Microsoft Learn

指定時間に呼び出されるコールバックは引数のcallbackで、TimerCallbackデリゲートの形式で指定します。

delegate void TimerCallback( Object state )
TimerCallback 代理人 (System.Threading) | Microsoft Learn

dueTimeperiodで、callbackの呼び出し方法を指定できます。

  • dueTimeを0 … タイマーをすぐに開始する。つまりcallbackをすぐに呼び出す
  • dueTimeをTimeout.Infinite … タイマーを開始しない。この場合Change()で後から開始できる
  • periodをTimeout.Infinite … callbackを周期的に呼び出さない

すぐにタイマーを開始しないならばTimer(TimerCallback)のコンストラクタでオブジェクトを生成し、後からChange()でdueTimeperiodを指定する方法もあります。ただしこのコンストラクタではコールバックへ渡すデータを指定できず、Timerオブジェクト自身がstateオブジェクトとして渡されます。

サンプルコード

void Main()
{
    System.Threading.Timer timer
        = new System.Threading.Timer( Method, null, 100, 200 );
}

void Method( Object state )
{
    // このメソッドが制御を戻すと、スレッドはスレッドプールに戻り次のタスクを待つ
}

これはラムダ式を用いると、次のようにも記述できます。

System.Threading.Timer timer = new System.Threading.Timer((state) =>
{
    // 別スレッドでの処理
}, null, 100, 200);

メソッド

Change()

public bool Change(
    int dueTime, // 遅延時間 [msec]
    int period   // 呼び出し周期 [msec]
)
Change(Int32, Int32) - Timer.Change メソッド (System.Threading) | Microsoft Learn
引数 作用
dueTime コールバックをすぐに呼び出す (タイマーをすぐに再開する)
Timeout.Infinite コールバックを呼び出さない (タイマーを停止する)

これ以降コールバックを呼び出さないのであって、すでに呼び出したコールバックが停止するわけではない

period 0 または Timeout.Infinite 周期的な呼び出しを無効にする

Dispose()

タイマーを確実に破棄するには、引数でWaitHandleを受け取るDispose()を呼びます。multithreading - c# System.Threading.Timer wait for dispose - Stack Overflow

public bool Dispose (
    System.Threading.WaitHandle notifyObject
    );
Dispose(WaitHandle) - Timer.Dispose Method (System.Threading) | Microsoft Learn
using (System.Threading.WaitHandle waitHandle = new System.Threading.ManualResetEvent(false))
{
    if (timer.Dispose(waitHandle))
    {
        // まだ破棄されていないならば、破棄されるのを待つ

        const int millisecondsTimeout = 1000;
        if (!waitHandle.WaitOne(millisecondsTimeout))
        {
            // 指定時間内に破棄されなかった
        }
    }
}
Microsoft Learnから検索