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

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

やりたいこと

System.Threading.Timerのタイマーを使ってみる

使い方

基本はこれ

System.Threading.Timer? threadingTimer;

private void Button_Click_1(object sender, RoutedEventArgs e)
{
    Debug.WriteLine($"{DateTime.Now} System.Threading.Timerタイマースタート(thread id = {Thread.CurrentThread.ManagedThreadId})");

    threadingTimer?.Dispose();
    threadingTimer = null;

    threadingTimer = new Timer((obj) =>
    {
        Debug.WriteLine($"{DateTime.Now} System.Threading.Timerタイマー満了(thread id = {Thread.CurrentThread.ManagedThreadId})");
    }, null, dueTime: 5000, period: Timeout.Infinite);
}

★結果

タイマーをスタートさせる上記処理を書いたボタンを連打したのが下記。

2024/06/18 23:23:22 System.Threading.Timerタイマースタート(thread id = 1)
2024/06/18 23:23:22 System.Threading.Timerタイマースタート(thread id = 1)
2024/06/18 23:23:23 System.Threading.Timerタイマースタート(thread id = 1)
2024/06/18 23:23:23 System.Threading.Timerタイマースタート(thread id = 1)
2024/06/18 23:23:23 System.Threading.Timerタイマースタート(thread id = 1)
2024/06/18 23:23:24 System.Threading.Timerタイマースタート(thread id = 1)
2024/06/18 23:23:24 System.Threading.Timerタイマースタート(thread id = 1)
2024/06/18 23:23:24 System.Threading.Timerタイマースタート(thread id = 1)
2024/06/18 23:23:24 System.Threading.Timerタイマースタート(thread id = 1)
2024/06/18 23:23:25 System.Threading.Timerタイマースタート(thread id = 1)
2024/06/18 23:23:25 System.Threading.Timerタイマースタート(thread id = 1)
2024/06/18 23:23:25 System.Threading.Timerタイマースタート(thread id = 1)
2024/06/18 23:23:30 System.Threading.Timerタイマー満了(thread id = 9)

newするときの引数について

dueTimeが、一回目に満了するまでの時間。

periodが、二回目以降に、繰り返し満了するまでの時間。

1回だけ時間を測りたい場合、

dueTimeに測りたい秒数(ms)を入れて、periodTimeout.Infiniteにしておくと、一度だけ満了してくれるタイマになる。

使ってみた感想

なにか、newすると同時に走り出すのが気持ち悪い気がする。
(なんとなく、newは最初にしておいて、Start()でスタートさせたい。)

実験コード

以前調べたSystem.Timers.Timerタイマと合わせて、WPFアプリで実験をしてみたときのコード。

using System.Diagnostics;
using System.Windows;
using System.Windows.Threading;

namespace WpfApp1
{
    public partial class MainWindow : Window
    {
        System.Timers.Timer? timersTimer;
        System.Threading.Timer? threadingTimer;
        System.Windows.Threading.DispatcherTimer dispatcherTimer;

        public MainWindow()
        {
            InitializeComponent();
            timersTimer = new System.Timers.Timer();

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

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

            // 満了時の処理
            timersTimer.Elapsed += ((s, e) =>
            {
                Debug.WriteLine($"{DateTime.Now} System.Timers.Timerタイマー満了(thread id = {Thread.CurrentThread.ManagedThreadId})");
            });

            //---------------------

            dispatcherTimer = new DispatcherTimer();
            dispatcherTimer.Interval = TimeSpan.FromSeconds(5);
            dispatcherTimer.Tick += ((s, e) =>
            {
                Debug.WriteLine($"{DateTime.Now} System.Windows.Threading.DispatcherTimerタイマー満了(thread id = {Thread.CurrentThread.ManagedThreadId})");
            });

        }

        // System.Timers.Timer
        private void Button_Click(object sender, RoutedEventArgs e)
        {
            Debug.WriteLine($"{DateTime.Now} System.Timers.Timerタイマースタート(thread id = {Thread.CurrentThread.ManagedThreadId})");

            timersTimer?.Stop();
            timersTimer?.Start();
        }

        // System.Threading.Timer
        private void Button_Click_1(object sender, RoutedEventArgs e)
        {
            Debug.WriteLine($"{DateTime.Now} System.Threading.Timerタイマースタート(thread id = {Thread.CurrentThread.ManagedThreadId})");

            threadingTimer?.Dispose();
            threadingTimer = null;

            threadingTimer = new Timer((obj) =>
            {
                Debug.WriteLine($"{DateTime.Now} System.Threading.Timerタイマー満了(thread id = {Thread.CurrentThread.ManagedThreadId})");
            }, null, dueTime: 0, period: 3000);
        }

        private void Button_Click_2(object sender, RoutedEventArgs e)
        {
            Debug.WriteLine($"{DateTime.Now} System.Windows.Threading.DispatcherTimerタイマースタート(thread id = {Thread.CurrentThread.ManagedThreadId})");

            dispatcherTimer.Start();
        }
    }
}

参考

System.Threading.Timer クラス

https://learn.microsoft.com/ja-jp/dotnet/standard/threading/timers#the-systemthreadingtimer-class