1.その他のコントロールに関するサンプル色々 |
1 .Windows タイマーとサーバーベース・タイマーとスレッド・タイマーの動作比較(321) 2 . 3 . 4 . 5 . 6 . 7 . 8 . 9 . 10. 11. 12. 13. 14. 15. 16. 17. 18. |
下記プログラムコードに関する補足・注意事項 動作確認:Windows 8.1 (Windows 7) / VB2013 (VB2010) / Framework 4.5.1 / 対象の CPU:x86 Option :[Compare Text] [Explicit On] [Infer On] [Strict On] Imports :追加なし 参照設定:追加なし その他 : : このサンプル等の内容を無断で転載、掲載、配布する事はお断りします。(私の修正・改訂・削除等が及ばなくなるので) 必要ならリンクをはるようにして下さい。(引用の場合は引用元のリンクを明記して下さい) |
1.Windows タイマーとサーバーベース・タイマーとスレッド・タイマーの動作比較(25_Sot_01) (旧、SampleNo.321) |
System.Windows.Forms.Timer このタイマーは、Windows フォームアプリケーションで使用できるように最適化されていて、ウィンドウで使用する必要があります。 System.Timers.Timer このタイマーは、サーバーベース・タイマーで、マルチスレッド環境においてワーカースレッドと共に使用するようにデザインされています。 サーバーベース・タイマーはスレッド間を移動して、発生した Elapsed イベントを処理できます。 このため、イベントを時間どおりに発生させるという点で、Windows のタイマーより正確です。 System.Threading.Timer スレッド・タイマーは、イベントの代わりにコールバックメソッドを使用する単純で軽量なタイマーで、 タスクを別々のスレッドで定期的に実行するのに便利です。 使用コントロール:Label1 / Label2 / Label3 / Button1 / Button2 / Button3 / Button4 /後は、プログラム作成 Windows.Forms.Timer と System.Timers.Timer は、ツールボックスから貼り付けて使用する事もできますが今回はプログラム上で作成。 Public Class Form1 Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click '各 Timer の開始処理 Dim myInterval As Integer = 1000 Count1 = 0 WindowsTimer.Interval = myInterval WindowsTimer.Start() Count2 = 0 ServerBaseTimer.Interval = myInterval ServerBaseTimer.Start() Count3 = 0 '第一引数を 0 にすると直ちにイベントを開始する(他の Timer と同期を取るために 1000 に) ThreadTimer.Change(myInterval, myInterval) End Sub Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click 'Timer の停止処理 WindowsTimer.Stop() ServerBaseTimer.Stop() ThreadTimer.Change(Threading.Timeout.Infinite, Threading.Timeout.Infinite) End Sub Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click System.Threading.Thread.Sleep(5000) End Sub Private Sub Button4_Click(sender As Object, e As EventArgs) Handles Button4.Click For i As Integer = 50000 To 0 Step -1 Debug.Print(Str(i) & " 回目です") Button4.Text = Str(i) & " 回目です" Button4.Refresh() If WindowsTimer.Enabled = False Then Exit For End If If (i Mod 1500 = 0) Then Application.DoEvents() End If Next Button4.Text = "なんらかの処理" End Sub '-------------------------------------------------------------------------------------------------------------- Private Sub WindowsTimer_Tick(sender As Object, e As EventArgs) Handles WindowsTimer.Tick 'Windows.Forms.Timer イベントの処理 Count1 += 1 Console.WriteLine("Count1 : " & Count1.ToString) Label1.Text = "WindowsTimer : " & Count1 End Sub '-------------------------------------------------------------------------------------------------------------- Private Sub ServerBaseTimer_Tick(source As Object, e As Timers.ElapsedEventArgs) 'Timers.Timer イベントの処理 Count2 += 1 Console.WriteLine("Count2 : " & Count2.ToString) 'ここでは、スレッドが異なるのでラベルに直接、表示できないので Invoke メソッド経由での表示 setLabel2(Count2.ToString) End Sub Private Delegate Sub SetLabel2Delegate(ByVal Text As String) Private Sub setLabel2(ByVal Text As String) '別スレッド上にあるコントロールに対する書き込み処理 'Invoke メソッドを呼び出す必要があるかどうかを調査 If (Label2.InvokeRequired) Then 'invoke メソッドを通じてコントロールを呼び出す必要がある場合は、 Dim callback = New SetLabel2Delegate(AddressOf setLabel2) 'Label2 があるスレッド上で、デリゲートを実行します Label2.Invoke(callback, Count2.ToString) Exit Sub End If 'Label2 があるスレッド上で、デリゲートが実行されたので直接書き込みが可能になる Label2.Text = "ServerBaseTimer : " & Text End Sub '-------------------------------------------------------------------------------------------------------------- Private Sub ThreadTimer_Tick(source As Object) 'Threading.Timer イベントの処理 Count3 += 1 Console.WriteLine("Count3 : " & Count3.ToString) 'ここでは、スレッドが異なるのでラベルに直接、表示できないので Invoke メソッド経由での表示 setLabel3(Count3.ToString) End Sub Private Delegate Sub SetLabel3Delegate(ByVal Text As String) Private Sub setLabel3(ByVal Text As String) '別スレッド上にあるコントロールに対する書き込み処理 'Invoke メソッドを呼び出す必要があるかどうかを調査 If (Label3.InvokeRequired) Then 'invoke メソッドを通じてコントロールを呼び出す必要がある場合は、 Dim callback = New SetLabel3Delegate(AddressOf setLabel3) 'Label3 があるスレッド上で、デリゲートを実行します Label3.Invoke(callback, Count3.ToString) Exit Sub End If 'Label3 があるスレッド上で、デリゲートが実行されたので直接書き込みが可能になる Label3.Text = "ThreadTimer : " & Text End Sub Public ThreadTimer As System.Threading.Timer Public ServerBaseTimer As System.Timers.Timer Public WithEvents WindowsTimer As System.Windows.Forms.Timer Private Count1 As Integer = 0 Private Count2 As Integer = 0 Private Count3 As Integer = 0 Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load 'Windows.Forms.Timer の作成 WindowsTimer = New Windows.Forms.Timer 'Timers.Timer の作成 ServerBaseTimer = New System.Timers.Timer AddHandler ServerBaseTimer.Elapsed, AddressOf ServerBaseTimer_Tick 'Threading.Timer の作成 ThreadTimer = New Threading.Timer(AddressOf ThreadTimer_Tick) End Sub Private Sub Form1_FormClosing(sender As Object, e As FormClosingEventArgs) Handles Me.FormClosing My.Settings.FormLocation = Me.Location My.Settings.FormSize = Me.Size Dim DelFileName As String = "" If System.IO.File.Exists(DelFileName) Then Dim result As DialogResult = MessageBox.Show("ファイル[" & DelFileName & "]を削除しますか。", _ "ファイルの削除確認", MessageBoxButtons.YesNo) If result = Windows.Forms.DialogResult.Yes Then 'ファイルを削除 Dim fi As New System.IO.FileInfo(DelFileName) fi.Delete() End If End If WindowsTimer.Stop() ServerBaseTimer.Stop() ThreadTimer.Change(Threading.Timeout.Infinite, Threading.Timeout.Infinite) End Sub End Class 図1.上記実行結果 上記の図でも解るように、Windows.Forms.Timer 以外は、Thread.Sleep(5000) 実行中やなんらかの処理中でもイベントが発生しております。 Windows.Forms.Timer は、スレッドが停止中等はイベントも停止してしまいます。 おことわり 私の覚えととして試した結果を掲載したもので、このような使い方、事例が正しいかは自信がありませんので、参考程度にとどめておいて下さい。 |
2. |
3. |
4. |
5. |
6. |
7. |
8. |
9. |
10. |
11. |
12. |
13. |
14. |
15. |
16. |
17. |
18. |
検索キーワード及びサンプルコードの別名(機能名) |