ソフトウェア開発者の日常

こだわりなく書きたいことを書いていきます。

c# タイマーを使った定期処理

C#GUIがあるプログラムを作成しています。
ajya.hatenablog.jp

定期的に実行したい機能があります。
定期的に実行したいタイミングは、毎日0時です。

毎日0時に実行という設定ができればいいのですが、検索して情報を探した結果、見つかりませんでした。
C#にタイマーがあるのはわかったので、使い方を検索したら、以下のページが見つかりました。
teratail.com

こちらのページの回答の、一番評価が高い回答のコードの通りにすれば、0時に実行はできるようになります。
残念ながら、僕の開発環境では、

timer1 = new Timer(Method1, null, time1, new TimeSpan(24, 0, 0));

のコードがエラーとなってしまします。
エラーになるのは、Formで使おうとしているためのようです。

ソフトウェア開発者
Photo by ThisisEngineering RAEng on Unsplash

エラーを回避するコードを検索した結果、以下のようなコードになりました。

private static Timer timer1;

private void Form1_Load(object sender, EventArgs e)
{
    //  time1に0時までの時間を代入
    var time1 = DateTime.Today + new TimeSpan(24, 0, 0) - DateTime.Now;

    timer1 = new Timer();
    timer1.Tick += new EventHandler(Timer_Elapsed);
    timer1.Tick += new EventHandler(Button1_Click);
    timer1.Interval = (int)time1.TotalMilliseconds;
    timer1.Enabled = true;
}

public void Timer_Elapsed(object sender, EventArgs e)
{
    if (timer1.Interval != 24 * 60 * 60 * 1000)
    {
        timer1.Interval = 24 * 60 * 60 * 1000;
    }
}

0時までの時間をIntervalプロパティに指定しています。
docs.microsoft.com

Intervalプロパティががそのままでは、0時毎になりません。
0時毎にするために、タイマーの間隔が経過した際に発生するTickイベントに、Intervalプロパティが24時間ではなかったら、24時間に変更するコードを割り当てました。
docs.microsoft.com

24時間に変更した後のTickイベントで、実行したい処理を割り当てています。

Tickイベントの割り当てをこの順序にしたのは、実行したい処理に時間がかかった場合、Intervalプロパティを24時間に変更するコードの実行が遅くなるため、次回の実行が、実行にかかった時間+24時間後になってしまうためです。

このコードで毎日0時に定期的に処理が実行できるようになりました。