VB.NET Tips - 複数のTimerコントロールの使い方
Timerコントロールを複数使う場合の注意点などを例を挙げて説明します。
尚、単体でのTimerコントロールの使い方については以下のページを参照下さい。
⇒Timerコントロールの使い方
複数のTimerコントロールをフォームに張り付けた場合には、
タイマイベントの発生が同じ時間間隔を設定しておいても同時には発生しません。
同時に起こった場合には最初に発生したイベントの処理が終わった後でしか
次のイベントが発生しない様です。
フォーム上に貼られた複数のTimerコントロールは同一のスレッド内で
動作しているためだと思います。
実際のプログラムでそのことを見ていきます。
先ず、フォーム上にTimerコントロールを2個貼り、Timer1、Timer2とします。
さらに表示用にTextBoxコントロールを貼り、MultiLineをTrueとし、ScrollbarをVerticalに設定します。
また、タイマーの開始・終了を行うButtonコントロールを貼ります。
フォームロードイベントではTimerの間隔を100msec(0.1sec)に設定し、
「開始」「停止」ボタンクリックイベントでTimerを開始及び停止しています。
注目点は、タイマ1のTickイベントで、テキストボックスに現在時刻表示を行いますが、
その後にSleepによる待ち処理を行っています。
このSleepは待ち時間が終わるまでは戻ってこないので、Tickイベントが待たされることになります。
複数のTimerコントロールの使い方
01 | Public Class frmTimerMul |
06 | Private Sub frmTimer_Load(sender As Object , e As EventArgs) Handles Me .Load |
10 | Me .Timer1.Interval = 100 |
11 | Me .Timer2.Interval = 100 |
13 | Me .Timer1.Enabled = False |
14 | Me .Timer2.Enabled = False |
20 | Private Sub Timer1_Tick(sender As Object , e As EventArgs) Handles Timer1.Tick |
22 | Me .TextBox1.Text &= "Timer1 = " & Now.ToString( "hh:mm:ss.fff" ) & vbCrLf |
25 | System.Threading.Thread.Sleep(5 * 1000) |
31 | Private Sub Timer2_Tick(sender As Object , e As EventArgs) Handles Timer2.Tick |
33 | Me .TextBox1.Text &= "Timer2 = " & Now.ToString( "hh:mm:ss.fff" ) & vbCrLf |
39 | Private Sub btnStop_Click(sender As Object , e As EventArgs) Handles btnStop.Click |
48 | Private Sub btnStart_Click(sender As Object , e As EventArgs) Handles btnStart.Click |
このプログラムを実行すると以下の様な表示になります。
Timer1の時刻表示が行われ、5秒後にTimer2の時刻表示が行われます。
Timer1、Timer2ともに0.1秒毎のタイマイベントが発生するのですが
Timer1のタイマイベントでは
Sleepによる5秒の待ちが在るため、
Timer2のタイマイベントが待たされている様です。
尚、Timer2のタイマイベント処理はすぐに終わるため、
Timer2の時刻と次のTimer1の時刻はほぼ同じものとなります。
そこで以下の様にして考察してみます。
Timer1、Timer2ともに5秒毎のインターバルとし、
Timer1のタイマイベント処理に
MsgBoxの待ちを入れてみます。
Timerコントロールでの注意すること
01 | Public Class frmTimerMul2 |
06 | Private Sub frmTimer_Load(sender As Object , e As EventArgs) Handles Me .Load |
10 | Me .Timer1.Interval = 5000 |
11 | Me .Timer2.Interval = 5000 |
13 | Me .Timer1.Enabled = False |
14 | Me .Timer2.Enabled = False |
20 | Private Sub Timer1_Tick(sender As Object , e As EventArgs) Handles Timer1.Tick |
22 | Dim strTime As String = "Timer1 = " & Now.ToString( "hh:mm:ss.fff" ) & vbCrLf |
23 | Me .TextBox1.Text &= strTime |
25 | MsgBox( "Waiting..." & strTime, MsgBoxStyle.OkOnly, "タイマ1Tickイベント" ) |
31 | Private Sub Timer2_Tick(sender As Object , e As EventArgs) Handles Timer2.Tick |
33 | Me .TextBox1.Text &= "Timer2 = " & Now.ToString( "hh:mm:ss.fff" ) & vbCrLf |
39 | Private Sub btnStop_Click(sender As Object , e As EventArgs) Handles btnStop.Click |
48 | Private Sub btnStart_Click(sender As Object , e As EventArgs) Handles btnStart.Click |
これを実行して10数秒そのままにしておくと、以下の様なことが起こります。
Timer1のタイマイベントの中に
MsgBoxを入れたことによりこの様になりました。
MsgBoxはボタンを持った1個のウインドウの様なもので、
この処理の中でウインドウのメッセージ処理が行われているため
Timer1の次のタイマイベントの処理が受け付けられてしまい、次々と
MsgBoxの表示がされてしまいます。
(ウインドウのメッセージ処理については、ここでは説明しませんが
MsgBoxが行われることで
他のイベント処理を受付可能になるということです)
結果、タイマイベント処理の中ではあまり時間のかかる処理や、別のイベントを誘発するような処理は行わない方が良い様です。
(このことは、複数のTimerだからということではありませんが)