Results 1 to 11 of 11

Thread: [RESOLVED] complicated timer loop

  1. #1

    Thread Starter
    Lively Member
    Join Date
    Jul 2009
    Posts
    98

    Resolved [RESOLVED] complicated timer loop

    i have the following code to ping a list of switches , basically i want to add a timer to run at the end once the pings are finished and when the timer reaches a pre-determined value (long frequency) i want the ping process to start again , i want this process to keep repeating until btnoff is pressed. im having trouble because the code uses multithreading and ui threads whcih im not too familiar with.

    ive tried adding in the timer below which ive commented out because it was giving an error when the pings were completed.
    any ideas ?

    **code is posted below
    Last edited by markhorgan1; Feb 9th, 2010 at 10:47 AM. Reason: over 10,000 characters

  2. #2

    Thread Starter
    Lively Member
    Join Date
    Jul 2009
    Posts
    98

    Re: complicated timer loop

    Code:
    Imports System.Data
    Imports System.Data.OleDb
    Public Class Form5
    
        Dim frequency As Long
        Private Sub btnON_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnON.Click
    
            If ComboBox1.Text = "" Then    ' ensures combo box is not left blank
    
                MsgBox("Please select scan frequency", [vbOKOnly])       ' prompts user to enter scan frequency
    
                'sets scan frequency
            Else
                btnBack.Enabled = False
                ComboBox1.Enabled = False
                lblMin.Enabled = False
                lblFrequency.Enabled = False
                btnOff.Enabled = True
                btnON.Enabled = False
                lblOff.Visible = False
                PictureBox1.Visible = False
                lblOn.Visible = True
                PictureBox2.Visible = True               'enables/hides the relevant picture boxs, labels and buttons based on user selection
    
            RichTextBox1.Visible = True
    
           Counter = 0 'reset the counter in case this is not the first time the ping button has been clicked
    
    
                Dim bgthread As New Threading.Thread(AddressOf BG_CollectData)  'Create a new background thread
                bgthread.IsBackground = True  'Make the thread end if the program is closed
                bgthread.Start()              'Start the background thread
    
            End If
    
            If ComboBox1.Text = "15" Then
                frequency = 900000
    
            ElseIf ComboBox1.Text = "20" Then            ' 60000ms in minute
                frequency = 1200000
    
            ElseIf ComboBox1.Text = "30" Then
                frequency = 1800000
    
            ElseIf ComboBox1.Text = "60" Then
                frequency = 3600000000
    
            End If
    
        End Sub
    
        Private Sub btnOff_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnOff.Click
    
            btnBack.Enabled = True
            ComboBox1.Enabled = True
            lblMin.Enabled = True
            lblFrequency.Enabled = True
            btnON.Enabled = True
            btnOff.Enabled = False
            lblOn.Visible = False
            PictureBox2.Visible = False
            lblOff.Visible = True
            PictureBox1.Visible = True                   'enables/hides the relevant picture boxs, labels and buttons based on user selection
    
        End Sub
    
        Private Sub btnBack_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnBack.Click
    
            Me.Hide()          'hides current form
            Form3.Show()       'displays selected form
    
        End Sub
        ''' <summary>
        ''' Represents a network switch (or any device with an IP) that is in the database
        ''' </summary>
        Private Class NetworkSwitch
            Private _IPAddress As String
            Private _SwitchID As Integer
            Private _SwitchName As String
            Private _Result As Boolean
            Private _ResponseTime As Integer
    
            Public Property IPAddress() As String
                Get
                    Return _IPAddress
                End Get
                Set(ByVal value As String)
                    _IPAddress = value
                End Set
            End Property
            Public Property ResponseTime() As Integer
                Get
                    Return _ResponseTime
                End Get
                Set(ByVal value As Integer)
                    _ResponseTime = value
                End Set
            End Property
            Public Property SwitchName() As String
                Get
                    Return _SwitchName
                End Get
                Set(ByVal value As String)
                    _SwitchName = value
                End Set
            End Property
    
            Public Property SwitchID() As Integer
                Get
                    Return _SwitchID
                End Get
                Set(ByVal value As Integer)
                    _SwitchID = value
                End Set
            End Property
    
            Public Property Result() As Boolean
                Get
                    Return _Result
                End Get
                Set(ByVal value As Boolean)
                    _Result = value
                End Set
            End Property
     End Class
    
        'Set up some variables that we will use from various functions/subs
        Private PingList As List(Of NetworkSwitch)
    
        Private Counter As Integer = 0
        Private ConnString As New OleDbConnectionStringBuilder("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=H:\FYP-trial\NetworkMap\Network Map.mdb;User Id=admin;Password=;")
        'This is the Delegate that will be used to pass data between the threads safely
        Private Delegate Sub PingComplete(ByVal sw As NetworkSwitch)
      Private Sub BG_CollectData()
            'Create our connection that will be used to connect to the Access database
            Dim AccessConnection As New OleDbConnection(ConnString.ConnectionString)
    
            'Create the command that will be used to select all of the data in the IP and ID columns
            Dim SelectCommand As New OleDbCommand("SELECT * FROM tblSwitch ", AccessConnection)
    
     'Create a new instance of a list of our NetworkSwitch class
            PingList = New List(Of NetworkSwitch)
     'Open the connection to the database
            AccessConnection.Open()
    
     'Use a DataReader to access the data that the SELECT command returns
            Dim Reader As OleDbDataReader = SelectCommand.ExecuteReader
            'Start to loop through the results
            'This loop will be restarted for each row in the database
            Do While Reader.Read
     'Create a new instance of our NetworkSwitch class and populate the ID and IP properties
                'with data from the current row in the database that we are looping through
                Dim CurrentSwitch As New NetworkSwitch
                With CurrentSwitch
                    .SwitchID = Reader("SwitchID")
                    .SwitchName = Reader("SwitchName")
                    .IPAddress = Reader("IPAddress")
     End With
                'Add the new instance of the NetworkSwitch to our list
                PingList.Add(CurrentSwitch)
            Loop 'Start the loop again for the next record in the database
    
            'Close the connection because we have now processed all rows in the database
            AccessConnection.Close()
    
            'Give the threadpool a limit so that no more than 30 threads are running at the same time
            Threading.ThreadPool.SetMaxThreads(30, 400)
    
            'Loop through our list of NetworkSwitch instances and start (well, queue up) a new background
            'thread for each item in the list and passes it the current item in the loop (which is a NetworkSwitch object)
            For Each switchobject As NetworkSwitch In PingList
                Threading.ThreadPool.QueueUserWorkItem(New Threading.WaitCallback(AddressOf DoPing), switchobject)
            Next
    End Sub
    
        ''' <summary>
        ''' Performs the ping and updates the Result property of the NetworkSwitch object that was passed to this 
        ''' </summary>
     Private Sub DoPing(ByVal Switch As NetworkSwitch)
     Dim Result As Net.NetworkInformation.PingReply
            Dim SendPing As New Net.NetworkInformation.Ping
            Dim ResponseTime As Integer
     Result = SendPing.Send(Switch.IPAddress)
            ResponseTime = Result.RoundtripTime
    
            If Result.Status = Net.NetworkInformation.IPStatus.Success Then
                Switch.Result = True
                Switch.ResponseTime = ResponseTime
            Else
                Switch.Result = False
            End If
      UpdateDatabase(Switch)
            Counter += 1
            Me.Invoke(New PingComplete(AddressOf UI_PingComplete), Switch)
    
        End Sub
     ''' <summary>
        ''' This is executed each time a ping completes and the database has been updated.
        ''' It is executed on the UI thread because we used Me.Invoke to call it so it can access
        ''' controls on the UI thread without a problem
        ''' </summary>
        Private Sub UI_PingComplete(ByVal sw As NetworkSwitch)
    
            If sw.Result = True Then
                RichTextBox1.SelectionColor = Color.DarkBlue
            ElseIf sw.Result = False Then
    
                RichTextBox1.SelectionColor = Color.Red
    
            End If
    
            RichTextBox1.AppendText(sw.SwitchID & "--" & sw.SwitchName & " -- " & sw.IPAddress & " -- Reply -> " & sw.Result & "--ResponseTime--" & sw.ResponseTime & "ms" & vbNewLine) 'update our log textbox
    
            If Counter = PingList.Count Then
                RichTextBox1.AppendText(vbNewLine & vbNewLine & "Finished re-trying devices" & vbNewLine)
    
                MsgBox("Finished re-trying devices", [vbOKOnly])
                '  Timer1 = Nothing
                PingList = Nothing 'clean up
                '  Timer1.Enabled = True
                ' Timer1.Start()
    
                '  If Timer1.Equals(frequency) Then
                'Dim bgthread As New Threading.Thread(AddressOf BG_CollectData)  'Create a new background thread
                ' bgthread.IsBackground = True  'Make the thread end if the program is closed
                'bgthread.Start()              'Start the background thread
                ' End If
            End If
        End Sub
    
        Private Sub UpdateDatabase(ByVal sw As NetworkSwitch)
    
            Dim AccessConnection As New OleDbConnection(ConnString.ConnectionString)
    
            Dim UpdateCommand As New OleDbCommand("UPDATE tblSwitch SET Result=@Result, LastTested=@CurrentTime, ResponseTime=@ResponseTime WHERE SwitchID=@SwitchID", AccessConnection)
    
            With UpdateCommand.Parameters
                .Add("@Result", OleDbType.Boolean).Value = sw.Result
                .Add("@CurrentTime", OleDbType.Char).Value = Now.ToString
                .Add("@ResponseTime", OleDbType.Integer).Value = sw.ResponseTime
                .Add("@SwitchID", OleDbType.Integer).Value = sw.SwitchID
    
            End With
            AccessConnection.Open()   'dont delete
    
            UpdateCommand.ExecuteNonQuery()  'Execute the command that updates the database
     AccessConnection.Close()   'dont delete
    End Sub
    
    End Class

  3. #3
    Fanatic Member Megalith's Avatar
    Join Date
    Oct 2006
    Location
    Secret location in the UK
    Posts
    879

    Re: complicated timer loop

    Ah i see it:- this is the code you have wrong
    Code:
               MsgBox("Finished re-trying devices", [vbOKOnly])
                '  Timer1 = Nothing
                PingList = Nothing 'clean up
                '  Timer1.Enabled = True
                ' Timer1.Start()
    
                '  If Timer1.Equals(frequency) Then
                'Dim bgthread As New Threading.Thread(AddressOf BG_CollectData)  'Create a new background thread
                ' bgthread.IsBackground = True  'Make the thread end if the program is closed
                'bgthread.Start()              'Start the background thread
                ' End If
    the first part is right so keep this
    Code:
               MsgBox("Finished re-trying devices", [vbOKOnly])
               Timer1 = Nothing
               PingList = Nothing 'clean up
               Timer1.Enabled = True
               Timer1.Start()
    go onto the Design page for the form ands double click the timer, this creates a timer Tick sub to deal with when the timer has ticked. within this block paste this
    Code:
    Dim bgthread As New Threading.Thread(AddressOf BG_CollectData)  'Create a new background thread
    bgthread.IsBackground = True  'Make the thread end if the program is closed
    bgthread.Start()              'Start the background thread
    Timer1.Stop()                  'Stop the timer till you need to do the count again
    If debugging is the process of removing bugs, then programming must be the process of putting them in.

  4. #4

    Thread Starter
    Lively Member
    Join Date
    Jul 2009
    Posts
    98

    Re: complicated timer loop

    thanks megalith ive made those changes one last thing tho i cant seem to find how the timer knows when to tick ?

    is it done by setting the interval on the timer or do i set a value that the timer compares itself to ? e.g. like i originally had below

    Code:
    If Timer1.Equals(frequency) Then ....

  5. #5
    Fanatic Member Megalith's Avatar
    Join Date
    Oct 2006
    Location
    Secret location in the UK
    Posts
    879

    Re: complicated timer loop

    yes you set the interval on the timer (which is in millseconds) you can do it either in design or while the code runs, with this example, unless you do plan to change the delay) i'd do it in design.
    If debugging is the process of removing bugs, then programming must be the process of putting them in.

  6. #6

    Thread Starter
    Lively Member
    Join Date
    Jul 2009
    Posts
    98

    Re: complicated timer loop

    yeah i need to do it while the code runs because the interval is selected by the user before the loop runs for the first time. i tried setting the interval but I am now getting a nullreference error(object reference not set to an instance of an object) at this line after code runs for first time.

    Code:
    Me.Invoke(New PingComplete(AddressOf UI_PingComplete), Switch)

    ** ive posted the code with the timer changes below
    Last edited by markhorgan1; Feb 10th, 2010 at 10:04 AM. Reason: code posted below

  7. #7

    Thread Starter
    Lively Member
    Join Date
    Jul 2009
    Posts
    98

    Re: complicated timer loop

    Code:
    Imports System.Data
    Imports System.Data.OleDb
    Public Class Form5
    
        Dim frequency As Long
    
        Private Sub btnON_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnON.Click
    
            If ComboBox1.Text = "" Then    ' ensures combo box is not left blank
    
                MsgBox("Please select scan frequency", [vbOKOnly])       ' prompts user to enter scan frequency
    
    
    
                'sets scan frequency
    
    
            Else
                btnBack.Enabled = False
                ComboBox1.Enabled = False
                lblMin.Enabled = False
                lblFrequency.Enabled = False
                btnOff.Enabled = True
                btnON.Enabled = False
                lblOff.Visible = False
                PictureBox1.Visible = False
                lblOn.Visible = True
                PictureBox2.Visible = True               'enables/hides the relevant picture boxs, labels and buttons based on user selection
    
    
                RichTextBox1.Visible = True
    
                Counter = 0 'reset the counter in case this is not the first time the ping button has been clicked
    
    
                Dim bgthread As New Threading.Thread(AddressOf BG_CollectData)  'Create a new background thread
                bgthread.IsBackground = True  'Make the thread end if the program is closed
                bgthread.Start()              'Start the background thread
    
            End If
    
    
            If ComboBox1.Text = "15" Then
                frequency = 600000 ' should be 90 but 60 for demo sake
                'frequency = Timer1.Interval
            ElseIf ComboBox1.Text = "20" Then            ' 60000ms in minute
                frequency = 1200000
    
            ElseIf ComboBox1.Text = "30" Then
                frequency = 1800000
    
            ElseIf ComboBox1.Text = "60" Then
                frequency = 3600000000
    
    
            End If
    
        End Sub
    
    
        Private Sub btnOff_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnOff.Click
    
            btnBack.Enabled = True
            ComboBox1.Enabled = True
            lblMin.Enabled = True
            lblFrequency.Enabled = True
            btnON.Enabled = True
            btnOff.Enabled = False
            lblOn.Visible = False
            PictureBox2.Visible = False
            lblOff.Visible = True
            PictureBox1.Visible = True                   'enables/hides the relevant picture boxs, labels and buttons based on user selection
    
        End Sub
    
        Private Sub btnBack_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnBack.Click
    
            Me.Hide()          'hides current form
            Form3.Show()       'displays selected form
    
        End Sub
    
    
    
    
        Private Class NetworkSwitch
            Private _IPAddress As String
            Private _SwitchID As Integer
            Private _SwitchName As String
            Private _Result As Boolean
            Private _ResponseTime As Integer
    
    
            Public Property IPAddress() As String
                Get
                    Return _IPAddress
                End Get
                Set(ByVal value As String)
                    _IPAddress = value
                End Set
            End Property
            Public Property ResponseTime() As Integer
                Get
                    Return _ResponseTime
                End Get
                Set(ByVal value As Integer)
                    _ResponseTime = value
                End Set
            End Property
            Public Property SwitchName() As String
                Get
                    Return _SwitchName
                End Get
                Set(ByVal value As String)
                    _SwitchName = value
                End Set
            End Property
    
            Public Property SwitchID() As Integer
                Get
                    Return _SwitchID
                End Get
                Set(ByVal value As Integer)
                    _SwitchID = value
                End Set
            End Property
    
            Public Property Result() As Boolean
                Get
                    Return _Result
                End Get
                Set(ByVal value As Boolean)
                    _Result = value
                End Set
            End Property
    
        End Class
    
        
        Private PingList As List(Of NetworkSwitch)
    
        Private Counter As Integer = 0
        Private ConnString As New OleDbConnectionStringBuilder("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=H:\FYP-trial\NetworkMap\Network Map.mdb;User Id=admin;Password=;")
        'This is the Delegate that will be used to pass data between the threads safely
        Private Delegate Sub PingComplete(ByVal sw As NetworkSwitch)
    
    
       
        Private Sub BG_CollectData()
       
            Dim AccessConnection As New OleDbConnection(ConnString.ConnectionString)
    
     
            Dim SelectCommand As New OleDbCommand("SELECT * FROM tblSwitch ", AccessConnection)
    
            'Create a new instance of a list of our NetworkSwitch class
            PingList = New List(Of NetworkSwitch)
    
    
          
            AccessConnection.Open()
    
            'Use a DataReader to access the data that the SELECT command returns
            Dim Reader As OleDbDataReader = SelectCommand.ExecuteReader
            'Start to loop through the results
            'This loop will be restarted for each row in the database
            Do While Reader.Read
    
                'Create a new instance of our NetworkSwitch class and populate the ID and IP properties
                'with data from the current row in the database that we are looping through
                Dim CurrentSwitch As New NetworkSwitch
                With CurrentSwitch
                    .SwitchID = Reader("SwitchID")
                    .SwitchName = Reader("SwitchName")
                    .IPAddress = Reader("IPAddress")
    
                End With
                'Add the new instance of the NetworkSwitch to our list
                PingList.Add(CurrentSwitch)
            Loop 'Start the loop again for the next record in the database
    
            'Close the connection because we have now processed all rows in the database
            AccessConnection.Close()
    
            'Give the threadpool a limit so that no more than 30 threads are running at the same time
            Threading.ThreadPool.SetMaxThreads(30, 400)
    
            'Loop through our list of NetworkSwitch instances and start (well, queue up) a new background
            'thread for each item in the list and passes it the current item in the loop (which is a NetworkSwitch object)
            For Each switchobject As NetworkSwitch In PingList
                Threading.ThreadPool.QueueUserWorkItem(New Threading.WaitCallback(AddressOf DoPing), switchobject)
            Next
    
        End Sub
    
    
        Private Sub DoPing(ByVal Switch As NetworkSwitch)
    
            Dim Result As Net.NetworkInformation.PingReply
            Dim SendPing As New Net.NetworkInformation.Ping
            Dim ResponseTime As Integer
    
    
            Result = SendPing.Send(Switch.IPAddress)
            ResponseTime = Result.RoundtripTime
    
            If Result.Status = Net.NetworkInformation.IPStatus.Success Then
                Switch.Result = True
                Switch.ResponseTime = ResponseTime
            Else
                Switch.Result = False
            End If
    
            UpdateDatabase(Switch)
            Counter += 1
            Me.Invoke(New PingComplete(AddressOf UI_PingComplete), Switch)
    
        End Sub
    
      
        Private Sub UI_PingComplete(ByVal sw As NetworkSwitch)
    
            If sw.Result = True Then
                RichTextBox1.SelectionColor = Color.DarkBlue
            ElseIf sw.Result = False Then
    
                RichTextBox1.SelectionColor = Color.Red
    
            End If
    
            RichTextBox1.AppendText(sw.SwitchID & "--" & sw.SwitchName & " -- " & sw.IPAddress & " -- Reply -> " & sw.Result & "--ResponseTime--" & sw.ResponseTime & "ms" & vbNewLine) 'update our log textbox
    
            If Counter = PingList.Count Then
                RichTextBox1.AppendText(vbNewLine & vbNewLine & "Finished re-trying devices" & vbNewLine)
    
                MsgBox("Finished re-trying devices", [vbOKOnly])
                Timer1 = Nothing
                PingList = Nothing 'clean up
                Timer1.Enabled = True
                frequency = Timer1.Interval
                Timer1.Start()
    
                '  If Timer1.Equals(frequency) Then
                'Dim bgthread As New Threading.Thread(AddressOf BG_CollectData)  'Create a new background thread
                ' bgthread.IsBackground = True  'Make the thread end if the program is closed
                'bgthread.Start()              'Start the background thread
                ' End If
            End If
        End Sub
    
     
        Private Sub UpdateDatabase(ByVal sw As NetworkSwitch)
    
            Dim AccessConnection As New OleDbConnection(ConnString.ConnectionString)
    
            Dim UpdateCommand As New OleDbCommand("UPDATE tblSwitch SET Result=@Result, LastTested=@CurrentTime, ResponseTime=@ResponseTime WHERE SwitchID=@SwitchID", AccessConnection)
    
            With UpdateCommand.Parameters
                .Add("@Result", OleDbType.Boolean).Value = sw.Result
                .Add("@CurrentTime", OleDbType.Char).Value = Now.ToString
                .Add("@ResponseTime", OleDbType.Integer).Value = sw.ResponseTime
                .Add("@SwitchID", OleDbType.Integer).Value = sw.SwitchID
    
            End With
            AccessConnection.Open()   'dont delete
    
            UpdateCommand.ExecuteNonQuery()  'Execute the command that updates the database
    
            AccessConnection.Close()   'dont delete
    
        End Sub
    
    
    
    
        Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
            Dim bgthread As New Threading.Thread(AddressOf BG_CollectData)  'Create a new background thread
            bgthread.IsBackground = True  'Make the thread end if the program is closed
            bgthread.Start()              'Start the background thread
            Timer1.Stop()                  'Stop the timer till you need to do the count again
        End Sub
    End Class

  8. #8

    Thread Starter
    Lively Member
    Join Date
    Jul 2009
    Posts
    98

    Re: complicated timer loop

    i have the timer working now,few things were in the wrong place, but it only works when i set the interval in design view is there a way to set it equal to a long which the user specifies ? before / after the timer is enabled

  9. #9
    Fanatic Member Megalith's Avatar
    Join Date
    Oct 2006
    Location
    Secret location in the UK
    Posts
    879

    Re: complicated timer loop

    yes you simply use
    Code:
    Timer1.Interval = someTimeInMilliseconds
    glad you have it working though
    If debugging is the process of removing bugs, then programming must be the process of putting them in.

  10. #10

    Thread Starter
    Lively Member
    Join Date
    Jul 2009
    Posts
    98

    Re: [RESOLVED] complicated timer loop

    perfect , problem wasnt what i had but was where i was putting it

    thanks megalith

  11. #11
    Fanatic Member Megalith's Avatar
    Join Date
    Oct 2006
    Location
    Secret location in the UK
    Posts
    879

    Re: [RESOLVED] complicated timer loop

    no probs, glad i could help
    If debugging is the process of removing bugs, then programming must be the process of putting them in.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width