Reputation: 97
I have code that sends a ping to a batch of computers, and opens a VNC session to any that respond that they are online.
The pings are sent in a parallel.foreach loop, and an event is raised when a reply is receieved.
Despite putting a synclock block around the AddHost code, it is still being entered by multiple threads simultaneously.
I think it has something to do with the code being called by a raiseevent on another object.
This is the method that is handling the event
Private Sub AddHost(hostname As String)
' panesList is an list(of RemoteDesktop) prepopulated with 36 individual RemoteDesktop objects
Dim vnc As RemoteDesktop = panesList(Position)
vnc.GetPassword = New AuthenticateDelegate(Function() vncPassword)
SyncLock Semaphore
Try
If Position = 36 Then
Return
End If
vnc.Connect(hostname, 0, True, True)
Position += 1
Catch ex As Exception
End Try
End SyncLock
End Sub
Private Sub HandleConnect(hostFilter As String)
AddHandler OnlineFinder.LiveComputer, AddressOf AddHost
Dim bg As New Task(Sub() OnlineFinder.CheckFilteredASync(hostFilter))
bg.Start()
' AddHandler OnlineFinder.SearchComplete, AddressOf Finished
End Sub
From the object OnlineFinder.vb
Public Sub CheckFilteredASync(filterString As String)
Dim Ctable As DataTable = CTableAdapter.GetDataByPartName($"{filterString}%")
Dim clist As New List(Of String)
For Each drow As DataRow In Ctable.Rows
clist.Add(drow.Field(Of String)("Name"))
Next
Searching = True
Dim parallelLoopResult = Parallel.ForEach(clist, Sub(site) Ping(site))
RaiseEvent SearchComplete()
End Sub
Private Sub Ping(host As String)
If ValidPing(host) Then
RaiseEvent LiveComputer(host)
End If
End Sub
How should I be doing this so only one event is processed at a time (but it doesn't hang the UI)
Upvotes: 0
Views: 126