In my post Multithreading pings and showing them in a grid in VB.Net I got a question from Alex.
Hi,
What if I want to check 100 ip’s 5 at a time? What do I need to change in the code to accomplish this. I’ve been working on it for several hours with no luck.
And Alex was pushing his luck by coming back and asking this too.
Will it also be possible to pause/resume checking as this would be handy?
But I aim to please so I did what Alex wanted.
The app pings 6 Ip-addresses in groups of 2 in an Async matter.
You can pause the pings, and it will stop/pause as soon as it is finished with the 2 it was pinging.
I just added 2 extra menu items.
It just starts when you click Ping.
And it pauses when you click Pause.
And here is the enormous amount of code.
```vbnet Imports System.Threading Imports System.Threading.Tasks Imports System.Net.NetworkInformation
Partial Public Class Form1
Private fThread As Thread
Private fThread2 As Thread
Private waitHandle As ManualResetEvent = New ManualResetEvent(True)
Public Delegate Sub AddRowDelegate(ByVal column As Integer)
Delegate Sub CheckOnlineDelegate(ByVal rowindex As Integer)
Delegate Sub SetOnlineDelegate(ByVal rowindex As Integer)
Private success As New List(Of Integer)
Private done As New List(Of Integer)
Private Sub Form1_Load(ByVal sender As Object, ByVal e As EventArgs) Handles Me.Load
fGrid.Columns.Add("Ip", "Ip")
fGrid.Columns.Add("Ping", "Ping")
fGrid.Columns(0).Width = 100
fGrid.Columns(1).AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill
For i As Integer = 0 To 5
Dim myRowIndex = fGrid.Rows.Add()
fGrid.Rows(myRowIndex).Cells(0).Value = "10.216.110." & (11 + myRowIndex).ToString
Next
End Sub
Private Sub ThreadProc()
For i As Integer = 0 To 2
waitHandle.WaitOne()
Parallel.For(0 + (i * 2), 2 + (i * 2), Sub(b)
Do While Not done.Contains(b)
fGrid.Invoke(New AddRowDelegate(AddressOf AddRow), New Object() {b})
Thread.Sleep(300)
Loop
fGrid.Invoke(New SetOnlineDelegate(AddressOf SetOnline), New Object() {b})
End Sub)
Next
End Sub
Private Sub ThreadProc2()
For i As Integer = 0 To 2
waitHandle.WaitOne()
Parallel.For(0 + (i * 2), 2 + (i * 2), Sub(b)
CheckOnline(b)
End Sub)
Next
End Sub
Private Sub AddRow(ByVal rowindex As Integer)
If fGrid.Rows(rowindex).Cells(1).Value Is Nothing OrElse fGrid.Rows(rowindex).Cells(1).Value.ToString.Contains(".....") OrElse Not fGrid.Rows(rowindex).Cells(1).Value.ToString.Contains("Pinging") Then
fGrid.Rows(rowindex).Cells(1).Value = "Pinging 10.216.110." & (11 + rowindex).ToString & " "
Else
fGrid.Rows(rowindex).Cells(1).Value = fGrid.Rows(rowindex).Cells(1).Value.ToString & "."
End If
fGrid.Rows(rowindex).Cells(1).Style.BackColor = Drawing.Color.White
End Sub
Private Sub CheckOnline(ByVal rowindex As Integer)
Dim _ping As New Ping
Try
Dim _pingreply = _ping.Send("10.216.110." & (11 + rowindex).ToString, 2000)
If _pingreply.Status = IPStatus.Success Then
SyncLock success
success.Add(rowindex)
End SyncLock
End If
Catch ex As Exception
End Try
SyncLock done
done.Add(rowindex)
End SyncLock
End Sub
Private Sub SetOnline(ByVal rowindex As Integer)
If Not success.Contains(rowindex) Then
fGrid.Rows(rowindex).Cells(1).Value = "Offline"
fGrid.Rows(rowindex).Cells(1).Style.BackColor = Drawing.Color.Red
Else
fGrid.Rows(rowindex).Cells(1).Value = "Online"
fGrid.Rows(rowindex).Cells(1).Style.BackColor = Drawing.Color.Green
End If
End Sub
Private Sub PingToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles PingToolStripMenuItem.Click
done = New List(Of Integer)
success = New List(Of Integer)
fThread = New Thread(New ThreadStart(AddressOf ThreadProc))
fThread.IsBackground = True
fThread.Start()
fThread2 = New Thread(New ThreadStart(AddressOf ThreadProc2))
fThread2.IsBackground = True
fThread2.Start()
End Sub
Private Sub StopToolStripMenuItem_Click(sender As System.Object, e As System.EventArgs) Handles StopToolStripMenuItem.Click
waitHandle.Reset()
End Sub
Private Sub ResumeToolStripMenuItem_Click(sender As System.Object, e As System.EventArgs) Handles ResumeToolStripMenuItem.Click
waitHandle.Set()
End Sub
End Class``` Not pretty, but functional. I used the ManualResetEvent to Pause and resume the pings and I just added an extra for next to the Threadprocs to make the grouping happen.
All quite simple if you know how.