Imports System.Threading
Public Class ThreadTest
    Inherits System.Windows.Forms.Form

#Region " Windows Form Designer generated code "

    Public Sub New()
        MyBase.New()

        'This call is required by the Windows Form Designer.
        InitializeComponent()

        'Add any initialization after the InitializeComponent() call

    End Sub

    'Form overrides dispose to clean up the component list.
    Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
        If disposing Then
            If Not (components Is Nothing) Then
                components.Dispose()
            End If
        End If
        MyBase.Dispose(disposing)
    End Sub
            Friend WithEvents cmdStart As System.Windows.Forms.Button
    Friend WithEvents Timer1 As System.Windows.Forms.Timer
    Friend WithEvents Timer2 As System.Windows.Forms.Timer
    Friend WithEvents cmdTimer As System.Windows.Forms.Button
    Friend WithEvents GroupBox1 As System.Windows.Forms.GroupBox
    Friend WithEvents Label2 As System.Windows.Forms.Label
    Friend WithEvents Label6 As System.Windows.Forms.Label
    Friend WithEvents Label1 As System.Windows.Forms.Label
    Friend WithEvents Label5 As System.Windows.Forms.Label
    Friend WithEvents Label3 As System.Windows.Forms.Label
    Private components As System.ComponentModel.IContainer

    'Required by the Windows Form Designer

    'NOTE: The following procedure is required by the Windows Form Designer
    'It can be modified using the Windows Form Designer.  
    'Do not modify it using the code editor.
    <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
        Me.components = New System.ComponentModel.Container
        Me.Timer1 = New System.Windows.Forms.Timer(Me.components)
        Me.Timer2 = New System.Windows.Forms.Timer(Me.components)
        Me.cmdStart = New System.Windows.Forms.Button
        Me.cmdTimer = New System.Windows.Forms.Button
        Me.GroupBox1 = New System.Windows.Forms.GroupBox
        Me.Label2 = New System.Windows.Forms.Label
        Me.Label6 = New System.Windows.Forms.Label
        Me.Label1 = New System.Windows.Forms.Label
        Me.Label5 = New System.Windows.Forms.Label
        Me.Label3 = New System.Windows.Forms.Label
        Me.GroupBox1.SuspendLayout()
        Me.SuspendLayout()
        '
        'Timer1
        '
        '
        'Timer2
        '
        '
        'cmdStart
        '
        Me.cmdStart.Anchor = CType((System.Windows.Forms.AnchorStyles.Bottom Or System.Windows.Forms.AnchorStyles.Left), System.Windows.Forms.AnchorStyles)
        Me.cmdStart.Font = New System.Drawing.Font("Tahoma", 8.25!, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, CType(0, Byte))
        Me.cmdStart.Location = New System.Drawing.Point(20, 132)
        Me.cmdStart.Name = "cmdStart"
        Me.cmdStart.Size = New System.Drawing.Size(116, 32)
        Me.cmdStart.TabIndex = 2
        Me.cmdStart.Text = "Start With Threads"
        '
        'cmdTimer
        '
        Me.cmdTimer.Anchor = CType((System.Windows.Forms.AnchorStyles.Bottom Or System.Windows.Forms.AnchorStyles.Left), System.Windows.Forms.AnchorStyles)
        Me.cmdTimer.Font = New System.Drawing.Font("Tahoma", 8.25!, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, CType(0, Byte))
        Me.cmdTimer.Location = New System.Drawing.Point(20, 96)
        Me.cmdTimer.Name = "cmdTimer"
        Me.cmdTimer.Size = New System.Drawing.Size(116, 32)
        Me.cmdTimer.TabIndex = 2
        Me.cmdTimer.Text = "Start With Timers"
        '
        'GroupBox1
        '
        Me.GroupBox1.Anchor = CType((((System.Windows.Forms.AnchorStyles.Top Or System.Windows.Forms.AnchorStyles.Bottom) _
                    Or System.Windows.Forms.AnchorStyles.Left) _
                    Or System.Windows.Forms.AnchorStyles.Right), System.Windows.Forms.AnchorStyles)
        Me.GroupBox1.Controls.Add(Me.Label2)
        Me.GroupBox1.Controls.Add(Me.Label6)
        Me.GroupBox1.Controls.Add(Me.Label1)
        Me.GroupBox1.Controls.Add(Me.Label5)
        Me.GroupBox1.Location = New System.Drawing.Point(20, 12)
        Me.GroupBox1.Name = "GroupBox1"
        Me.GroupBox1.Size = New System.Drawing.Size(336, 68)
        Me.GroupBox1.TabIndex = 6
        Me.GroupBox1.TabStop = False
        '
        'Label2
        '
        Me.Label2.Font = New System.Drawing.Font("Tahoma", 8.25!, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, CType(0, Byte))
        Me.Label2.Location = New System.Drawing.Point(72, 40)
        Me.Label2.Name = "Label2"
        Me.Label2.Size = New System.Drawing.Size(68, 16)
        Me.Label2.TabIndex = 1
        '
        'Label6
        '
        Me.Label6.Location = New System.Drawing.Point(12, 40)
        Me.Label6.Name = "Label6"
        Me.Label6.Size = New System.Drawing.Size(60, 16)
        Me.Label6.TabIndex = 5
        Me.Label6.Text = "Counter 2:"
        '
        'Label1
        '
        Me.Label1.Font = New System.Drawing.Font("Tahoma", 8.25!, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, CType(0, Byte))
        Me.Label1.Location = New System.Drawing.Point(72, 20)
        Me.Label1.Name = "Label1"
        Me.Label1.Size = New System.Drawing.Size(68, 16)
        Me.Label1.TabIndex = 0
        '
        'Label5
        '
        Me.Label5.Location = New System.Drawing.Point(12, 20)
        Me.Label5.Name = "Label5"
        Me.Label5.Size = New System.Drawing.Size(60, 16)
        Me.Label5.TabIndex = 5
        Me.Label5.Text = "Counter 1:"
        '
        'Label3
        '
        Me.Label3.AutoSize = True
        Me.Label3.Location = New System.Drawing.Point(157, 96)
        Me.Label3.MaximumSize = New System.Drawing.Size(200, 0)
        Me.Label3.Name = "Label3"
        Me.Label3.Size = New System.Drawing.Size(199, 78)
        Me.Label3.TabIndex = 7
        Me.Label3.Text = "Note: This test performs a not-safe label update. This allows you to get a feelin" & _
            "g for the difference between executing threads and timers. However, it's not saf" & _
            "e enough for a real application."
        '
        'ThreadTest
        '
        Me.AutoScaleBaseSize = New System.Drawing.Size(5, 14)
        Me.ClientSize = New System.Drawing.Size(376, 190)
        Me.Controls.Add(Me.Label3)
        Me.Controls.Add(Me.GroupBox1)
        Me.Controls.Add(Me.cmdTimer)
        Me.Controls.Add(Me.cmdStart)
        Me.Font = New System.Drawing.Font("Tahoma", 8.25!, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, CType(0, Byte))
        Me.Name = "ThreadTest"
        Me.Text = "Timers Versus Threads"
        Me.GroupBox1.ResumeLayout(False)
        Me.ResumeLayout(False)
        Me.PerformLayout()

    End Sub

#End Region

    Private Delegate Sub UpdateLabelDelegate(ByVal label As Control, ByVal text As String)
    Private Sub UpdateLabel(ByVal label As Control, ByVal text As String)
        label.Text = text
        label.Refresh()
    End Sub

    Private Sub RefreshLabel1()
        For i As Integer = 1 To 5000
            UpdateLabel(Label1, i.ToString())

            ' The proper update (shown below) needs
            ' to interrupt the main thread, much like a timer,
            ' to make the label change.
            'Me.Invoke(New UpdateLabelDelegate(AddressOf UpdateLabel), Label1, i.ToString())
        Next
    End Sub

    Private Sub RefreshLabel2()
        For i As Integer = 1 To 5000
            UpdateLabel(Label2, i.ToString())

            ' The proper update (shown below) needs
            ' to interrupt the main thread, much like a timer,
            ' to make the label change.
            'Me.Invoke(New UpdateLabelDelegate(AddressOf UpdateLabel), Label2, i.ToString())
        Next
    End Sub

    Private Sub cmdStart_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdStart.Click
        Dim MyThread1 As New Thread(AddressOf RefreshLabel1)
        Dim MyThread2 As New Thread(AddressOf RefreshLabel2)
        MyThread1.Priority = ThreadPriority.BelowNormal
        MyThread2.Priority = ThreadPriority.BelowNormal
        MyThread1.Start()
        MyThread2.Start()
    End Sub

    Private Sub Timer1_Elapsed(ByVal sender As System.Object, _
    ByVal e As System.EventArgs) Handles Timer1.Tick
        For i As Integer = 1 To 5000
            UpdateLabel(Label1, i.ToString())
        Next
        Timer1.Enabled = False
    End Sub

    Private Sub Timer2_Elapsed(ByVal sender As System.Object, _
      ByVal e As System.EventArgs) Handles Timer2.Tick
        For i As Integer = 1 To 5000
            UpdateLabel(Label2, i)
        Next
        Timer2.Enabled = False
    End Sub

    Private Sub cmdTimer_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdTimer.Click
        Timer1.Enabled = True
        Timer2.Enabled = True
    End Sub

    Private Sub ThreadTest_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        ' This shouldn't be used in a real application!
        Control.CheckForIllegalCrossThreadCalls = False
    End Sub
End Class
