System.Timers.Timerのタイマーを使う

もくじ
https://tera1707.com/entry/2022/02/06/144447

やりたいこと

C#で使えるタイマーにはいろいろあるらしい。

タイマーはかなりよく使うので今更とりたててなにかあるわけではないのだが、 なぜか毎回「どれを使えばいいんだったか?」となる。

動けば別にどれを使ってもよいと個人的に思うが、ここらで一度それぞれ使い方をまとめたい。

とりあえず「System.Timers.Timer」から。

使い方

基本はこれ。

namespace ConsoleApp8
{
    internal class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine($"{DateTime.Now} スタート(thread id = {Thread.CurrentThread.ManagedThreadId})");

            var timer = new System.Timers.Timer();

            //繰り返しよばれたければtrue、1回だけで良ければfalse
            timer.AutoReset = false;

            // タイマ満了までの時間
            timer.Interval = 5000;

            // 満了時の処理
            timer.Elapsed += Timer_Elapsed;

            // タイマスタート
            timer.Start();

            Console.ReadLine();
        }

        private static void Timer_Elapsed(object? sender, System.Timers.ElapsedEventArgs e)
        {
            Console.WriteLine($"{DateTime.Now} タイマー満了(thread id = { Thread.CurrentThread.ManagedThreadId })");
        }
    }
}

結果

2024/06/18 22:57:03 スタート(thread id = 1)
2024/06/18 22:57:08 タイマー満了(thread id = 11)

タイマかけなおし

個人的によくあるのが、「短い間隔で複数回くるイベントの、最後だけとりたい」みたいなときに、「500ms以内に来たイベントは無視しする」みたいなの。

そういう場合は下記のようにした。

namespace ConsoleApp8
{
    internal class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine($"{DateTime.Now} スタート");

            var timer = new System.Timers.Timer();

            //繰り返しよばれたければtrue、1回だけで良ければfalse
            timer.AutoReset = false;

            // タイマ満了までの時間
            timer.Interval = 5000;

            // 満了時の処理
            timer.Elapsed += Timer_Elapsed;

            // タイマスタート
            timer.Start();

            // Start後にStop→Startすれば、タイマをかけなおし出来る
            Task.Run(() =>
            {
                for (int i = 0; i < 5; i++)
                {
                    Thread.Sleep(1000);

                    Console.WriteLine($"{DateTime.Now} タイマーかけなおし");
                    timer.Stop();
                    timer.Start();
                }
            });

            Console.ReadLine();
        }

        private static void Timer_Elapsed(object? sender, System.Timers.ElapsedEventArgs e)
        {
            Console.WriteLine($"{DateTime.Now} タイマー満了");
        }
    }
}

結果

2024/06/18 22:48:29 スタート
2024/06/18 22:48:30 タイマーかけなおし
2024/06/18 22:48:31 タイマーかけなおし
2024/06/18 22:48:32 タイマーかけなおし
2024/06/18 22:48:33 タイマーかけなおし
2024/06/18 22:48:34 タイマーかけなおし
2024/06/18 22:48:39 タイマー満了

参考

System.Timers.Timer クラス

https://learn.microsoft.com/ja-jp/dotnet/api/system.timers.timer?view=net-8.0