C#で動的なアプリケーション、例えばリアルタイムで表示が変わる時計や、一定時間ごとに何かをチェックするプログラムを作るにはどうすればよいのでしょうか。
この記事では、それを実現するための2つの重要な概念「タイマー」と「イベント」を解説し、それらを応用してコンソール上で動作するシンプルなデジタル時計を作成する手順を紹介します。これらの知識は、将来的にボタンなどがある本格的なGUIアプリケーションを作る上での基礎となります。
現在時刻の取得方法
まず基本として、C#で現在の時刻を取得する方法を確認しましょう。これはDateTime
というクラス(正確には構造体)を使うことで簡単に実現できます。
DateTime.Now
プロパティを使うと、プログラムを実行しているコンピュータの現在の日付と時刻を取得できます。
// 現在の日付と時刻を取得
DateTime currentTime = DateTime.Now;
// 年、月、日、時、分、秒を個別に取り出す
Console.WriteLine(currentTime.Year + "年");
Console.WriteLine(currentTime.Month + "月");
Console.WriteLine(currentTime.Day + "日");
Console.WriteLine(currentTime.Hour + "時");
Console.WriteLine(currentTime.Minute + "分");
Console.WriteLine(currentTime.Second + "秒");
// ToString()を使って指定した書式で表示することも可能
Console.WriteLine(currentTime.ToString("yyyy/MM/dd HH:mm:ss"));
タイマーとイベントとは?
時計のように、リアルタイムで何かを処理し続けるプログラムには、「タイマー」と「イベント」という仕組みが不可欠です。
タイマー (Timer)
タイマーは、「一定時間ごとに合図(イベント)を発生させる」目覚まし時計のようなものです。「100ミリ秒ごと」「1秒ごと」といった間隔(Interval
)を設定できます。
イベント (Event)
イベントとは、プログラム内で起こる「出来事」の通知です。タイマーの場合は「指定した時間が経過したよ!」という合図がイベントにあたります。ユーザーがボタンをクリックした際の「クリックされたよ!」という合図もイベントの一種です。
イベントハンドラー (Event Handler)
イベントハンドラーは、「イベントという合図が発生したときに、実際に実行される処理」のことです。タイマーのイベントに対して、「時刻を更新して表示する」という処理を紐づけることで、時計が実現できます。この「イベントに処理を紐づけること」を「イベントを購読する」などと表現します。
コンソールで時計を作ってみよう
それでは、System.Timers.Timer
クラスを使って、コンソール上で動作するデジタル時計を作成します。
実装のステップ
Timer
のインスタンスを作成し、イベントを発生させる間隔(Interval
)を1000ミリ秒(=1秒)に設定します。- タイマーのイベント(
Elapsed
)が発生したときに実行されるイベントハンドラー(メソッド)を定義します。 - イベントハンドラーの中には、「現在時刻を取得して、画面に表示する」処理を記述します。
timer.Elapsed += イベントハンドラー名;
という形で、タイマーのイベントと処理を結びつけます。timer.Start()
でタイマーを開始します。
完成コード
using System;
using System.Timers; // Timerクラスを使うために必要
class Program
{
// Timerをクラスのフィールドとして宣言し、どこからでもアクセスできるようにする
private static System.Timers.Timer clockTimer;
static void Main(string[] args)
{
// 1. タイマーを1秒間隔で設定
clockTimer = new System.Timers.Timer(1000);
// 4. タイマーのElapsedイベントに、OnTickメソッドを紐づける
clockTimer.Elapsed += OnTick;
// タイマーが自動でリセットされるように設定
clockTimer.AutoReset = true;
// 5. タイマーを開始
clockTimer.Enabled = true; // Start()と同じ効果
Console.WriteLine("デジタル時計を開始しました。何かキーを押すと終了します。");
// プログラムがすぐに終了しないように待機
Console.ReadKey();
// タイマーを停止(プログラム終了前にリソースを解放するのが丁寧)
clockTimer.Stop();
clockTimer.Dispose();
}
// 2. イベントハンドラー(1秒ごとに呼び出されるメソッド)
private static void OnTick(Object source, ElapsedEventArgs e)
{
// 3. 現在時刻を取得して、指定の書式で表示
string timeString = e.SignalTime.ToString("HH:mm:ss");
// コンソールのカーソルを左上(0,0)に移動させて、常に同じ位置に表示する
Console.SetCursorPosition(0, 1);
Console.Write("現在の時刻: " + timeString);
}
}
このコードでは、Console.SetCursorPosition
を使って、時刻が更新されるたびにコンソールの同じ位置に上書き表示することで、スクロールせずにデジタル時計のように見せる工夫をしています。
スタート・ストップ機能の追加
Timer
クラスには、動作を制御するためのStart()
メソッドとStop()
メソッド(またはEnabled
プロパティ)が用意されています。
先ほどのコードでは、プログラムが終了するまで時計が動き続けましたが、これを改良して、ユーザーの入力で時計を開始・停止できるようにしてみましょう。
Main
メソッド内の抜粋
// (タイマーの設定は同じ)
Console.WriteLine("コマンドを入力してください (start, stop, exit)");
while (true) // 無限ループでユーザーの入力を待つ
{
string command = Console.ReadLine();
if (command == "start")
{
clockTimer.Start(); // clockTimer.Enabled = true; と同じ
Console.WriteLine("時計を開始しました。");
}
else if (command == "stop")
{
clockTimer.Stop(); // clockTimer.Enabled = false; と同じ
Console.WriteLine("時計を停止しました。");
}
else if (command == "exit")
{
break; // whileループを抜ける
}
}
clockTimer.Dispose(); // プログラム終了
まとめ
今回は、タイマーとイベントという、動的なアプリケーションを作成するための重要な概念を学びました。
DateTime.Now
で現在の時刻を取得できる。Timer
クラスは、一定間隔でイベントを発生させる仕組み。- イベントハンドラーは、イベント発生時に実行される処理(メソッド)。
timer.Elapsed += OnTick;
のように、イベントとハンドラーを紐づける。Start()
とStop()
でタイマーの動作を制御できる。
これらの基本を理解すれば、時計だけでなく、一定時間ごとにデータを更新するアプリや、簡単なゲームなど、作れるプログラムの幅が大きく広がります。