タイマにより一定時間間隔で処理を行うには?(Windowsタイマ編):.NET TIPS
Windowsフォームアプリでは、System.Windows.Forms.Timerクラス(Timerコンポーネント)を使うことで、一定間隔で処理を実行できるようになる。
本稿は2005/11/11に初版公開された記事を改訂し 、Visual Studio 2017でコードの動作検証、図版の追加、全般的な構成の変更などを行ったものです。
.NET Frameworkには一定時間間隔で処理を行う(メソッドを呼び出す)ためのタイマ機能として、以下の3種類のTimerクラスが用意されている。
本稿では1のWindowsタイマについて、その基本的な使い方をまとめる。
特定のトピックをすぐに知りたいという方は以下のリンクを活用してほしい。
Windowsタイマ:System.Windows.Forms.Timerクラス
Windowsアプリ(Windowsフォームアプリ)でタイマを利用したい場合には、通常System.Windows.Forms名前空間のTimerクラスを利用する。
このタイマはWindows OSのタイマメッセージ(WM_TIMERメッセージ)をベースにしており、タイマを利用するにはメッセージループの実行が必要である(一般的なWindowsフォームアプリはApplication.Runメソッドの呼び出しを含んでおり、このメソッドによりメッセージループが実行される)。
このTimerクラスでは、EventHandlerデリゲート(System名前空間)を使用して、タイマにより呼び出されるメソッド(以下、タイマメソッドと記す)のデリゲートを作成し、TimerクラスのTickイベントに登録する。
タイマメソッドの呼び出し間隔はIntervalプロパティにより設定し(単位はミリ秒)、タイマの開始/停止は、Enabledプロパティにtrue/falseを設定して行う(あるいはStart/Stopメソッドを呼び出してもよい)。
以下にWindowsタイマを使用したサンプルプログラムを示す。このプログラムではTimerクラスに関する記述を分かりやすくするために、コンソールアプリとして記述している。MyClockメソッドがタイマにより一定間隔で実行されるメソッドである。Visual StudioでC#/VBのコンソールアプリプロジェクトを新規に作成して、以下のコードを試す場合には、System.Windows.Formsアセンブリへの参照をプロジェクトに追加する必要がある。また、VBではソリューションエクスプローラーの[My Project]をダブルクリックして、[アプリケーション]タブにある[スタートアップ オブジェクト]に[Sub Main]か[FormsTimerTest]に変更する必要がある。
// formstimer.cs
using System;
using System.Windows.Forms;
public class FormsTimerTest {
static void Main() {
FormsTimerTest ftt = new FormsTimerTest();
ftt.Run();
}
public void Run() {
Timer timer = new Timer();
timer.Tick += new EventHandler(MyClock);
timer.Interval = 1000;
timer.Enabled = true; // timer.Start()と同じ
Application.Run(); // メッセージループを開始
}
public void MyClock(object sender, EventArgs e) {
Console.WriteLine(DateTime.Now);
// 出力例:
// 2005/11/08 19:59:10
// 2005/11/08 19:59:11
// 2005/11/08 19:59:12
// ……
}
}
// コンパイル方法:csc formstimer.cs
' formstimer.vb
Imports System
Imports System.Windows.Forms
Public Class FormsTimerTest
Shared Sub Main()
Dim ftt As FormsTimerTest = New FormsTimerTest()
ftt.Run()
End Sub
Public Sub Run()
Dim timer As Timer = New Timer()
AddHandler timer.Tick, New EventHandler(AddressOf MyClock)
timer.Interval = 1000
timer.Enabled = true ' timer.Start()と同じ
Application.Run() ' メッセージループを開始
End Sub
Public Sub MyClock(sender As Object, e As EventArgs)
Console.WriteLine(DateTime.Now)
' 出力例:
' 2005/11/08 19:59:10
' 2005/11/08 19:59:11
' 2005/11/08 19:59:12
' ……
End Sub
End Class
' コンパイル方法:vbc formstimer.vb
Windowsフォームの場合
Visual Studioでプログラミングしている場合には、ツールボックスの[すべての Windows フォーム]タブからTimerコンポーネントをフォームにドラッグ&ドロップするだけでタイマが利用可能な状態となる(次の画像)。配置したTimerコンポーネントをダブルクリックすれば、タイマメソッド(Tickイベントハンドラ)が自動的に作成される。
ツールボックスからTimerコンポーネントをフォームに貼り付ける(Visual Studio 2017)
ツールボックス上部の検索窓を使うとすぐに見つけられる。
Timerコンポーネントをフォームにドロップすると、フォームの下に別の区画ができて、そこに配置される。
配置したTimerコンポーネントのプロパティペインで、Intervalプロパティ(=呼び出し間隔)とEnabledプロパティ(=タイマの開始/停止)を設定する(次の画像)。Enabledプロパティをtrueにしておけば、アプリ起動と同時にタイマがスタートする。
後は、先ほど作っておいたタイマメソッド(Tickイベントハンドラ)に、定期的に実行したい処理を書けばよい。例えば、フォームに配置したLabelコントロール(名前は「label1」)に現在時刻を表示するなら、次のコードのようになる。
private void timer1_Tick(object sender, EventArgs e)
{
this.label1.Text = DateTime.Now.ToLongTimeString();
}
Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
Me.label1.Text = DateTime.Now.ToLongTimeString()
End Sub
Labelコントロールの位置とフォントを適当に設定して実行してみると、次の画像のようになる。
Windowsタイマを利用するときの注意点
なお冒頭で述べたように、このタイマはWindows OSのメッセージをベースとしているため、タイマメッセージが発生したときに他のメッセージの処理を行っているとタイマメソッドは呼び出されない。また、その間に発生した複数のタイマメッセージは1つにまとめられる。
例えば、呼び出し間隔を1秒に設定したタイマを開始し、ボタンがクリックされたときの処理を3秒間にわたって行ったとすると、タイマメソッドが呼び出されるのはボタンのクリック処理が終わった直後となる。
このため、Windowsアプリで定期的な処理を確実に実行したい場合には、マルチスレッドにより動作する(前述の)スレッドタイマかサーバベースタイマの利用を検討する必要がある。
また、Windowsタイマの精度は55ミリ秒である。それよりも短い間隔で実行したい場合も、スレッドタイマかサーバベースタイマを利用する。
カテゴリ:Windowsフォーム 処理対象:Timerコンポーネント
使用ライブラリ:Timerコンポーネント(System.Windows.Forms名前空間)
使用ライブラリ:EventHandlerデリゲート(System名前空間)
関連TIPS:タイマにより一定時間間隔で処理を行うには?(スレッド・タイマ編)
関連TIPS:タイマにより一定時間間隔で処理を行うには?(サーバベース・タイマ編)
更新履歴
【2018/11/07】Visual Studio 2017でコードの動作検証、図版の追加、全般的な構成の変更などを行いました。
【2005/11/11】初版公開。
Copyright© Digital Advantage Corp. All Rights Reserved.