【C#】Timerクラスの活用方法10選を初心者向けに解説 – JPSM

【C#】Timerクラスの活用方法10選を初心者向けに解説

C#のTimerクラスを使ったプログラムのイメージC#

 

【サイト内のコードはご自由に個人利用・商用利用いただけます】

このサービスは複数のSSPによる協力の下、運営されています。

この記事では、プログラムの基礎知識を前提に話を進めています。

説明のためのコードや、サンプルコードもありますので、もちろん初心者でも理解できるように表現してあります。

また、理解しにくい説明や難しい問題に躓いても、JPSMがプログラミングの解説に特化してオリジナルにチューニングした画面右下のAIアシスタントに質問していだければ、特殊な問題でも指示に従い解決できるように作ってあります。

基本的な知識があればカスタムコードを使って機能追加、目的を達成できるように作ってあります。

※この記事は、一般的にプロフェッショナルの指標とされる『実務経験10,000時間以上』を凌駕する現役のプログラマチームによって監修されています。

サイト内のコードを共有する場合は、参照元として引用して下さいますと幸いです

※Japanシーモアは、常に解説内容のわかりやすさや記事の品質に注力しております。不具合、分かりにくい説明や不適切な表現、動かないコードなど気になることがございましたら、記事の品質向上の為にお問い合わせフォームにてご共有いただけますと幸いです。
(送信された情報は、プライバシーポリシーのもと、厳正に取扱い、処分させていただきます。)

はじめに

この記事では、C#で利用される「Timerクラス」について、初心者の方でも理解しやすいように徹底的に解説していきます。

Timerクラスは、特定の時間が経過した後に特定のコードを実行するために使用される非常に便利なツールです。

この記事を読み終える頃には、Timerクラスの基本から応用までをマスターし、様々なシナリオで活用できるようになるでしょう。

●Timerクラスの基礎知識

Timerクラスは、C#のSystem.Timers名前空間に属しており、定期的にイベントを発生させるために使われます。

これは、例えばユーザーに定期的な更新を通知したり、特定の時間が経過した後にタスクを実行したりする際に役立ちます。

Timerクラスは、特定の間隔で繰り返し処理を行うために設計されており、非常に柔軟に設定を変更することができます。

○Timerクラスとは

Timerクラスは、指定された時間間隔ごとにElapsedイベントを発生させる機能を持っています。

このElapsedイベントは、Timerが開始されてから指定された時間が経過するたびに発生し、イベントハンドラーを介して特定のアクションを実行することができます。

重要なのは、Timerクラスを使うことでプログラムの実行フローを適切に管理し、定期的なタスクを簡単に処理できるようになる点です。

○Timerクラスの基本的な使い方

Timerクラスを使う基本的なステップは次の通りです。

まず、Timerオブジェクトを作成し、その後にイベントハンドラーをElapsedイベントに関連付けます。

そして、Intervalプロパティを設定してタイマーの間隔を指定し、Startメソッドを呼び出してタイマーを開始します。

タイマーを停止するには、Stopメソッドを呼び出します。

これらの基本的な手順をマスターすれば、Timerクラスを効果的に活用するための基盤が築けます。

●Timerクラスの基本的な使い方

Timerクラスを使いこなすことは、C#プログラミングにおいて非常に有益です。

基本的な使い方をマスターすることで、時間に基づいた処理を自在に操ることができるようになります。

ここでは、Timerクラスの基本的な使い方とその応用について説明します。

○サンプルコード1:シンプルなタイマーの設定

まず最初に、単純なタイマーの設定方法を見てみましょう。

下記のサンプルコードは、指定された時間が経過するとメッセージを表示する単純なタイマーを設定します。

using System;
using System.Timers;

public class SimpleTimer
{
    private static Timer aTimer;

    public static void Main()
    {
        // タイマーのインスタンスを作成
        aTimer = new Timer(2000); // 2000ミリ秒(2秒)ごとにイベント発生

        // Elapsedイベントにイベントハンドラを関連付け
        aTimer.Elapsed += OnTimedEvent;

        // タイマーを開始
        aTimer.AutoReset = true;
        aTimer.Enabled = true;

        Console.WriteLine("Press the Enter key to exit the program...");
        Console.ReadLine();
    }

    private static void OnTimedEvent(Object source, ElapsedEventArgs e)
    {
        Console.WriteLine("The Elapsed event was raised at {0:HH:mm:ss.fff}", e.SignalTime);
    }
}

このコードでは、Timerクラスのインスタンスを作成し、2秒ごとにElapsedイベントが発生するように設定しています。

Elapsedイベントが発生すると、OnTimedEventメソッドが呼び出され、現在の時刻がコンソールに表示されます。

○サンプルコード2:繰り返し実行されるタイマー

次に、繰り返し実行されるタイマーの設定方法を見てみましょう。

下記のサンプルコードは、定期的に特定のタスクを実行するタイマーの例です。

using System;
using System.Timers;

public class RepeatTimer
{
    private static Timer aTimer;

    public static void Main()
    {
        // タイマーのインスタンスを作成
        aTimer = new Timer(5000); // 5000ミリ秒(5秒)ごとにイベント発生

        // Elapsedイベントにイベントハンドラを関連付け
        aTimer.Elapsed += OnTimedEvent;

        // タイマーを開始
        aTimer.AutoReset = true;
        aTimer.Enabled = true;

        Console.WriteLine("Press the Enter key to exit the program...");
        Console.ReadLine();
    }

    private static void OnTimedEvent(Object source, ElapsedEventArgs e)
    {
        Console.WriteLine("Repeated event at {0:HH:mm:ss.fff}", e.SignalTime);
    }
}

この例では、5秒ごとにOnTimedEventメソッドが呼び出され、現在の時刻がコンソールに表示されます。

これにより、定期的にタスクを実行するタイマーを簡単に設定することができます。

●Timerクラスの応用例

Timerクラスは基本的な使い方だけでなく、さまざまな応用が可能です。

特に、複雑なアプリケーションでは、複数のタイマーを管理したり、非同期処理を行ったりすることが求められます。

ここでは、そのような応用例をいくつか紹介し、その使い方を詳しく解説します。

○サンプルコード3:UIスレッドでのタイマー使用

UIアプリケーションでは、UIスレッド上でタイマーを使用する必要があります。

下記のサンプルコードは、UIスレッドでタイマーを使用して定期的にUIを更新する方法を表しています。

using System;
using System.Timers;
using System.Windows.Forms;

public class UITimer : Form
{
    private Timer aTimer;
    private Label label;

    public UITimer()
    {
        // ラベルの初期化
        label = new Label();
        label.AutoSize = true;
        label.Location = new System.Drawing.Point(50, 50);
        this.Controls.Add(label);

        // タイマーの初期化
        aTimer = new Timer(1000); // 1秒ごと
        aTimer.Elapsed += OnTimedEvent;
        aTimer.AutoReset = true;
        aTimer.Enabled = true;
    }

    private void OnTimedEvent(Object source, ElapsedEventArgs e)
    {
        this.Invoke((Action)(() =>
        {
            label.Text = $"現在時刻: {DateTime.Now.ToString("HH:mm:ss")}";
        }));
    }

    [STAThread]
    public static void Main()
    {
        Application.EnableVisualStyles();
        Application.Run(new UITimer());
    }
}

このコードでは、System.Windows.Formsを使用してUIを構築し、タイマーイベントでラベルのテキストを更新しています。

UIスレッドでのタイマー使用では、Invokeメソッドを使ってスレッドセーフな方法でUIを更新することが重要です。

○サンプルコード4:タイマーを使った非同期処理

非同期処理では、バックグラウンドでのタスク実行にタイマーが役立ちます。

下記のサンプルコードは、タイマーを使って非同期的にタスクを実行する一例です。

using System;
using System.Timers;
using System.Threading.Tasks;

public class AsyncTimer
{
    private Timer aTimer;

    public AsyncTimer()
    {
        // タイマーの設定
        aTimer = new Timer(5000); // 5秒ごと
        aTimer.Elapsed += async (sender, e) => await HandleTimer();
        aTimer.AutoReset = true;
        aTimer.Enabled = true;
    }

    private async Task HandleTimer()
    {
        Console.WriteLine("非同期タスク開始: " + DateTime.Now.ToString("HH:mm:ss"));
        // 長い処理を模擬
        await Task.Delay(1000);
        Console.WriteLine("非同期タスク終了: " + DateTime.Now.ToString("HH:mm:ss"));
    }

    public static void Main()
    {
        new AsyncTimer();
        Console.WriteLine("タイマーが開始されました。何かキーを押して終了してください...");
        Console.ReadKey();
    }
}

この例では、5秒ごとに非同期的なタスクを実行しています。

Task.Delayメソッドを使って模擬的な長い処理を表現しており、タイマーイベント内で非同期メソッドを呼び出しています。

○サンプルコード5:複数のタイマーを同時に管理

複数のタイマーを同時に管理することも可能です。

下記のサンプルコードは、2つのタイマーを同時に動かし、それぞれ異なる間隔でイベントを発生させる方法を表しています。

using System;
using System.Timers;

public class MultipleTimers
{
    private Timer timer1, timer2;

    public MultipleTimers()
    {
        // タイマー1の設定
        timer1 = new Timer(3000); // 3秒ごと
        timer1.Elapsed += (sender, e) => Console.WriteLine("タイマー1: " + DateTime.Now.ToString("HH:mm:ss"));
        timer1.AutoReset = true;
        timer1.Enabled = true;

        // タイマー2の設定
        timer2 = new Timer(5000); // 5秒ごと
        timer2.Elapsed += (sender, e) => Console.WriteLine("タイマー2: " + DateTime.Now.ToString("HH:mm:ss"));
        timer2.AutoReset = true;
        timer2.Enabled = true;
    }

    public static void Main()
    {
        new MultipleTimers();
        Console.WriteLine("複数のタイマーが開始されました。何かキーを押して終了してください...");
        Console.ReadKey();
    }
}

このコードでは、異なる間隔で2つのタイマーが設定されています。

各タイマーは独立して動作し、それぞれのタイミングでコンソールにメッセージを出力します。

●Timerクラスを活用した実践的なプログラム例

Timerクラスは単に時間を計測するだけではなく、より複雑な用途にも使用できます。

ここでは、実際のアプリケーションで役立ついくつかの具体的な使用例を紹介します。

○サンプルコード6:カウントダウンタイマーの作成

カウントダウンタイマーは、特定のイベントまでの時間を測るのに非常に便利です。

下記のサンプルコードは、指定した時間までカウントダウンし、完了時にメッセージを表示するタイマーの設定方法を表しています。

using System;
using System.Timers;

public class CountdownTimer
{
    private static Timer aTimer;
    private static int remainingTime = 10; // 10秒でカウントダウン

    public static void Main()
    {
        // タイマーの初期化
        aTimer = new Timer(1000); // 1秒ごと
        aTimer.Elapsed += OnTimedEvent;
        aTimer.AutoReset = true;
        aTimer.Enabled = true;

        Console.WriteLine("カウントダウンを開始します...");
        Console.ReadLine();
    }

    private static void OnTimedEvent(Object source, ElapsedEventArgs e)
    {
        if (remainingTime > 0)
        {
            Console.WriteLine($"残り時間: {remainingTime}秒");
            remainingTime--;
        }
        else
        {
            Console.WriteLine("カウントダウン終了!");
            aTimer.Stop();
        }
    }
}

このコードでは、タイマーが1秒ごとにOnTimedEventメソッドを呼び出し、remainingTime変数をデクリメントしています。

カウントダウンが0に達すると、「カウントダウン終了!」と表示し、タイマーを停止します。

○サンプルコード7:タイマーを使ったアニメーション

タイマーはアニメーションの制御にも使用できます。

下記のサンプルコードは、タイマーを使用して簡単なアニメーションを生成する方法を表しています。

using System;
using System.Timers;
using System.Drawing;
using System.Windows.Forms;

public class AnimationTimer : Form
{
    private Timer aTimer;
    private int positionX = 0;
    private const int StepSize = 5;

    public AnimationTimer()
    {
        // タイマーの初期化
        aTimer = new Timer(100); // 0.1秒ごと
        aTimer.Elapsed += OnTimedEvent;
        aTimer.AutoReset = true;
        aTimer.Enabled = true;

        // ウィンドウの設定
        this.DoubleBuffered = true;
        this.Paint += new PaintEventHandler(this.OnPaint);
        this.Size = new Size(400, 200);
    }

    private void OnTimedEvent(Object source, ElapsedEventArgs e)
    {
        positionX += StepSize;
        if (positionX > this.Width)
        {
            positionX = 0;
        }
        this.Invalidate(); // 画面を再描画
    }

    private void OnPaint(object sender, PaintEventArgs e)
    {
        Graphics g = e.Graphics;
        g.FillEllipse(Brushes.Blue, new Rectangle(positionX, 50, 50, 50));
    }

    [STAThread]
    public static void Main()
    {
        Application.EnableVisualStyles();
        Application.Run(new AnimationTimer());
    }
}

この例では、タイマーが0.1秒ごとに位置を更新し、OnPaintメソッドを使って青い円を新しい位置に描画しています。

これにより、円が画面を横切って動くアニメーションが作成されます。

○サンプルコード8:タイマーを活用したゲームのタイム管理

ゲーム開発では、タイマーを使ってゲーム内の時間を管理することが一般的です。

下記のサンプルコードは、ゲーム内で制限時間を設定し、時間経過に応じてプレイヤーに通知する方法を表しています。

using System;
using System.Timers;

public class GameTimer
{
    private static Timer gameTimer;
    private static int timeLimit = 60; // 制限時間は60秒

    public static void Main()
    {
        gameTimer = new Timer(1000); // 1秒ごと
        gameTimer.Elapsed += OnTimedEvent;
        gameTimer.AutoReset = true;
        gameTimer.Enabled = true;

        Console.WriteLine("ゲーム開始!制限時間は60秒です。");
    }

    private static void OnTimedEvent(Object source, ElapsedEventArgs e)
    {
        timeLimit--;

        if (timeLimit > 0)
        {
            Console.WriteLine($"残り時間: {timeLimit}秒");
        }
        else
        {
            Console.WriteLine("時間切れ!ゲームオーバー!");
            gameTimer.Stop();
        }
    }
}

このコードでは、ゲームの開始時に制限時間を60秒に設定し、1秒ごとにタイマーが残り時間を更新します。

時間が0になったらゲームオーバーの通知を行い、タイマーを停止します。

○サンプルコード9:バックグラウンドでのタスク実行

タイマーはバックグラウンドでのタスク実行にも役立ちます。

下記のサンプルコードは、一定間隔でバックグラウンドタスクを実行する方法を表しています。

using System;
using System.Timers;
using System.Threading.Tasks;

public class BackgroundTask
{
    private static Timer backgroundTimer;

    public static void Main()
    {
        backgroundTimer = new Timer(5000); // 5秒ごと
        backgroundTimer.Elapsed += async (sender, e) => await RunBackgroundTask();
        backgroundTimer.AutoReset = true;
        backgroundTimer.Enabled = true;

        Console.WriteLine("バックグラウンドタスクを開始しました。");
    }

    private static async Task RunBackgroundTask()
    {
        Console.WriteLine("バックグラウンドタスク実行中...");
        // 何らかの処理をここに記述
        await Task.Delay(1000); // 仮の遅延
        Console.WriteLine("バックグラウンドタスク完了");
    }
}

このコードでは、5秒ごとにRunBackgroundTaskメソッドを非同期で実行します。

実際のアプリケーションでは、ここにデータの処理や更新など、任意のバックグラウンドタスクを記述します。

○サンプルコード10:タイマーによる定期的なデータ更新

アプリケーションでは、タイマーを使って定期的にデータを更新することがよくあります。

下記のサンプルコードは、定期的にデータを更新する方法を表しています。

using System;
using System.Timers;

public class DataUpdateTimer
{
    private static Timer updateTimer;

    public static void Main()
    {
        updateTimer = new Timer(10000); // 10秒ごと
        updateTimer.Elapsed += OnTimedEvent;
        updateTimer.AutoReset = true;
        updateTimer.Enabled = true;

        Console.WriteLine("定期的なデータ更新を開始します。");
    }

    private static void OnTimedEvent(Object source, ElapsedEventArgs e)
    {
        Console.WriteLine("データを更新中...");
        // データ更新のロジックをここに記述
        Console.WriteLine("データ更新完了");
    }
}

このコードでは、10秒ごとにデータを更新する処理を実行します。

実際のアプリケーションでは、データベースの更新、APIへの問い合わせ、ファイルの読み書きなど、さまざまなデータ更新作業をこのタイミングで行うことができます。

●Timerクラスの注意点と対処法

Timerクラスを使用する際には、いくつかの注意点があります。

これらを理解し、適切に対処することで、より安定したアプリケーションを開発することが可能です。

○注意点1:タイマーの精度とリソースの使用

Timerクラスは内部的にシステムのタイマー機能を利用しているため、他のプロセスとのリソース競合が起こる可能性があります。

また、タイマーの精度はシステムの負荷によって変動することがあるため、高精度を要求する用途には不向きです。

特に、多くのタイマーを同時に使用する場合、システムに大きな負荷をかける可能性があるため注意が必要です。

○注意点2:マルチスレッド環境でのタイマー使用

Timerクラスはマルチスレッド環境で使用する際に特に注意が必要です。

タイマーのイベントは別スレッドで実行されるため、スレッドセーフなコーディングが求められます。

特に、UIコンポーネントにアクセスする場合は、UIスレッドでの操作を確実に行う必要があります。

○対処法:タイマーの誤動作を避けるためのテクニック

タイマーの誤動作を避けるためには、次のテクニックを利用すると良いでしょう。

  1. タイマーの間隔は、アプリケーションの要件に応じて慎重に設定します。不必要に短い間隔は避け、システムの負荷を考慮した設定が重要
  2. マルチスレッド環境では、スレッドセーフなコードを記述し、特にUIスレッドへのアクセスは適切な方法(例えば、Invokeメソッドの使用)で行う
  3. タイマーのイベント内では例外処理を適切に行い、予期せぬエラーからアプリケーションを保護する
  4. タイマーを使用しないときは、必ずDisposeメソッドを呼び出してリソースを適切に解放する

これらの点を意識することで、タイマーを安全にかつ効果的に使用することができます。

●Timerクラスのカスタマイズ方法

C#のTimerクラスは、基本的な機能だけでなく、特定のニーズに合わせてカスタマイズすることが可能です。

ここでは、カスタムタイマーの作成と、特定の条件下でのタイマーの挙動のカスタマイズ方法について解説します。

○カスタムタイマーの作成

タイマーの動作を特定の要件に合わせてカスタマイズするには、Timerクラスを継承して新しいクラスを作成する方法があります。

下記のサンプルコードは、カスタムタイマーの基本的な構造を表しています。

using System;
using System.Timers;

public class CustomTimer : Timer
{
    // カスタムタイマーの追加プロパティやメソッドを定義
    public int CustomProperty { get; set; }

    public CustomTimer(double interval) : base(interval)
    {
        // タイマーの初期化やカスタム設定
        this.Elapsed += OnCustomTimedEvent;
    }

    private void OnCustomTimedEvent(Object source, ElapsedEventArgs e)
    {
        // カスタムイベントの処理
        Console.WriteLine($"カスタムタイマーイベント発生: {DateTime.Now}, CustomProperty: {CustomProperty}");
    }
}

public class Program
{
    public static void Main()
    {
        CustomTimer timer = new CustomTimer(1000) { CustomProperty = 10 };
        timer.Start();

        Console.WriteLine("カスタムタイマーを開始しました。");
        Console.ReadLine();
    }
}

この例では、Timerクラスを継承し、独自のプロパティやイベントハンドラーを持つカスタムタイマーを作成しています。

○特定の条件下でのタイマーの挙動のカスタマイズ

タイマーの動作を特定の条件に基づいてカスタマイズすることも可能です。

例えば、アプリケーションの状態に応じてタイマーの間隔を変更することが考えられます。

下記のサンプルコードは、実行中の条件に応じてタイマーの間隔を変更する方法を表しています。

using System;
using System.Timers;

public class ConditionalTimer
{
    private Timer aTimer;
    private int condition = 0;

    public ConditionalTimer()
    {
        aTimer = new Timer(1000); // 初期間隔1秒
        aTimer.Elapsed += OnTimedEvent;
        aTimer.AutoReset = true;
        aTimer.Enabled = true;
    }

    private void OnTimedEvent(Object source, ElapsedEventArgs e)
    {
        condition++;

        // 特定の条件に基づいてタイマーの間隔を変更
        if (condition % 5 == 0)
        {
            aTimer.Interval = 2000; // 条件に合致した場合、間隔を2秒に変更
            Console.WriteLine("タイマー間隔を2秒に変更しました。");
        }

        Console.WriteLine($"タイマーイベント発生: {DateTime.Now}");
    }

    public static void Main()
    {
        new ConditionalTimer();
        Console.WriteLine("条件付きタイマーを開始しました。");
        Console.ReadLine();
    }
}

このコードでは、タイマーイベントが発生するたびにcondition変数が増加し、特定の条件(ここではconditionが5の倍数の時)でタイマーの間隔が変更されます。

まとめ

この記事では、C#のTimerクラスについて、その基礎から応用、注意点、カスタマイズ方法に至るまでを幅広く解説しました。

Timerクラスは、単に時間の経過を測るだけでなく、定期的なタスク実行など様々なシナリオで利用することができる強力なツールです。

このクラスの基本的な使い方をマスターすることで、時間に関連する多様な機能をプログラムに組み込むことが可能となります。

この記事を通じて、読者の皆さんがC#のTimerクラスの深い理解を得られたことを願います。

さまざまなプログラミングのシナリオにおいて、Timerクラスを効果的に活用していただきたいと思います。