タイマー

.NET には、マルチスレッド環境で使用するタイマーが 3 つあります。

Note

一部の .NET 実装には追加タイマーが含まれています。

  • System.Windows.Forms.Timer: 一定の間隔でイベントを発生させる Windows フォーム コンポーネント。 このコンポーネントにはユーザー インターフェイスがなく、シングルスレッド環境で使用するように設計されています。
  • System.Web.UI.Timer: 非同期または同期の Web ページのポストバックを一定の間隔で実行する ASP.NET コンポーネント。
  • System.Windows.Threading.DispatcherTimer: 指定の間隔と指定の優先順位で処理される Dispatcher キューに統合されるタイマー。

System.Threading.Timer クラス

System.Threading.Timer クラスによって、指定の間隔でデリゲートを連続的に呼び出すことができます。 このクラスを使用し、指定の間隔でデリゲートの呼び出しを 1 つスケジュールすることもできます。 デリゲートは ThreadPool スレッドで実行されます。

System.Threading.Timer オブジェクトを作成するとき、呼び出しメソッドを定義する TimerCallback デリゲート、呼び出しに渡される任意の状態オブジェクト、最初の呼び出しまで遅らせる時間、呼び出し間隔を指定します。 保留中のタイマーを取り消すには、Timer.Dispose メソッドを呼び出します。

次の例では、1 秒 (1000 ミリ秒) 後に最初の指定デリゲートを呼び出し、その後、2 秒おきに呼び出すタイマーが作成されます。 この例の状態オブジェクトは、デリゲートを呼び出す回数を数えるために使用されます。 デリゲートが少なくとも 10 回呼び出されると、タイマーが停止します。

using namespace System;
using namespace System::Threading;

ref class TimerState
{
public:
    int counter;
};

ref class Example
{
private:
    static Timer^ timer;

public:
    static void TimerTask(Object^ state)
    {
        Console::WriteLine("{0:HH:mm:ss.fff}: starting a new callback.", DateTime::Now);

        TimerState^ timerState = dynamic_cast<TimerState^>(state);
        Interlocked::Increment(timerState->counter);
    }

    static void Main()
    {
        TimerCallback^ tcb = gcnew TimerCallback(&TimerTask);
        TimerState^ state = gcnew TimerState();
        state->counter = 0;
        timer = gcnew Timer(tcb, state, 1000, 2000);

        while (state->counter <= 10)
        {
            Thread::Sleep(1000);
        }

        timer->~Timer();
        Console::WriteLine("{0:HH:mm:ss.fff}: done.", DateTime::Now);
    }
};

int main()
{
    Example::Main();
}
using System;
using System.Threading;
using System.Threading.Tasks;

class Program
{
    private static Timer timer;

    static void Main(string[] args)
    {
        var timerState = new TimerState { Counter = 0 };

        timer = new Timer(
            callback: new TimerCallback(TimerTask),
            state: timerState,
            dueTime: 1000,
            period: 2000);

        while (timerState.Counter <= 10)
        {
            Task.Delay(1000).Wait();
        }

        timer.Dispose();
        Console.WriteLine($"{DateTime.Now:HH:mm:ss.fff}: done.");
    }

    private static void TimerTask(object timerState)
    {
        Console.WriteLine($"{DateTime.Now:HH:mm:ss.fff}: starting a new callback.");
        var state = timerState as TimerState;
        Interlocked.Increment(ref state.Counter);
    }

    class TimerState
    {
        public int Counter;
    }
}
Imports System.Threading

Module Program

    Private Timer As Timer

    Sub Main(args As String())

        Dim StateObj As New TimerState
        StateObj.Counter = 0

        Timer = New Timer(New TimerCallback(AddressOf TimerTask), StateObj, 1000, 2000)

        While StateObj.Counter <= 10
            Task.Delay(1000).Wait()
        End While

        Timer.Dispose()
        Console.WriteLine($"{DateTime.Now:HH:mm:ss.fff}: done.")
    End Sub

    Private Sub TimerTask(ByVal StateObj As Object)

        Console.WriteLine($"{DateTime.Now:HH:mm:ss.fff}: starting a new callback.")

        Dim State As TimerState = CType(StateObj, TimerState)
        Interlocked.Increment(State.Counter)
    End Sub

    Private Class TimerState
        Public Counter As Integer
    End Class
End Module

使用例を含む詳細については、「System.Threading.Timer」を参照してください。

System.Timers.Timer クラス

マルチスレッド環境で使用できる別のタイマーが System.Timers.Timer です。このタイマーは既定で、ThreadPool スレッドでイベントを発生させます。

System.Timers.Timer オブジェクトを作成するとき、Elapsed イベントを発生させる間隔を指定できます。 Enabled プロパティを使用し、タイマーが Elapsed イベントを発生させるかどうかを示します。 指定間隔の経過後、1 回だけ Elapsed イベントを発生させる必要がある場合、AutoResetfalse に設定します。 AutoReset プロパティの既定値は true です。Interval プロパティで定義される間隔で Elapsed イベントが発生します。

使用例を含む詳細については、「System.Timers.Timer」を参照してください。

System.Threading.PeriodicTimer クラス

System.Threading.PeriodicTimer クラスを使用すると、指定した間隔の個々のティックを待機し、PeriodicTimer.WaitForNextTickAsync の呼び出し後に作業を実行できます。

System.Threading.PeriodicTimer オブジェクトを作成するときは、タイマーの各ティック間の時間の長さを決定する TimeSpan を指定します。 前のタイマー クラスのようにコールバックを渡したり、イベント ハンドラーを設定したりする代わりに、スコープ内で直接作業を実行し、WaitForNextTickAsync が指定した間隔でタイマーを進めるのを待機します。

WaitForNextTickAsync メソッドからは ValueTask<bool> が返され、タイマーが正常に発生した場合は truefalse の呼び出しによってタイマーが取り消された場合は PeriodicTimer.Dispose になります。 WaitForNextTickAsync には必要に応じて CancellationToken を指定でき、取り消しが要求されたときに TaskCanceledException が発生します。

詳細については、「System.Threading.PeriodicTimer」を参照してください。

関連項目