Question

Je travaille sur un programme qui scanne une liste des serveurs pour des informations différentes.

Tout fonctionne bien, sauf parfois je reçois des erreurs lorsque les discussions sont faites. Soit par l'analyse ou l'achèvement du bouton d'annulation arrêter la boucle, mais en laissant les fils actuels continuent.

Je vois le dire interface utilisateur l'analyse est terminée, mais le progressUpdate essaie de courir à nouveau. Je peux résoudre le problème en faisant un Thread.sleep plus après la WaitAll.

Pour la plupart, il attend le dernier fil mais je reçois une erreur parfois en disant qu'il ne peut pas accéder à la fonction progressUpdate parce OperationsComplete a déjà été exécuté.

J'obtiens l'erreur à BackgroundWorker1.ReportProgress (_completedCount, ScanResult) ci-dessous, mais il ne doit pas être appeler parce que WaitAll devrait attendre jusqu'à ce que les fils soient complets.

Private Sub ScanIsDone(ByVal ar As IAsyncResult)
    Dim d As PingDelegate = DirectCast(ar.AsyncState, PingDelegate)
    Dim ScanResult As ServerInfo = d.EndInvoke(ar)

    SyncLock (_lockObject)
        _completedCount = _completedCount + 1
        BackgroundWorker1.ReportProgress(_completedCount, ScanResult)
    End SyncLock
End Sub



Private Sub BackgroundWorker1_DoWork (ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork

    Dim servers As List(Of ServerInfo) = DirectCast(e.Argument, List(Of ServerInfo))
    Dim waitHandles As New List(Of WaitHandle)
    Dim waitHandles2 As New List(Of WaitHandle)
    Dim waitHandles3 As New List(Of WaitHandle)
    Dim waitHandles4 As New List(Of WaitHandle)

    For Each server As ServerInfo In servers
        _ThreadsOpen += 1
        _WaitCountAll += 1
        Dim d As New PingDelegate(AddressOf ScanServer)
        Dim ar As IAsyncResult = d.BeginInvoke(server, AddressOf ScanIsDone, d)
        Select Case _WaitCountAll
            Case 1 To 64
                waitHandles.Add(ar.AsyncWaitHandle)
            Case 65 To 128
                waitHandles2.Add(ar.AsyncWaitHandle)
            Case 129 To 192
                waitHandles3.Add(ar.AsyncWaitHandle)
            Case 193 To 256
                waitHandles4.Add(ar.AsyncWaitHandle)
        End Select

        While _ThreadsOpen > _ThreadMax - 1
            Thread.Sleep(200)
        End While
        If Cancel_Scan = True Then Exit For

    Next

    If waitHandles.Count <> 0 Then WaitHandle.WaitAll(waitHandles.ToArray())
    If waitHandles2.Count <> 0 Then WaitHandle.WaitAll(waitHandles2.ToArray())
    If waitHandles3.Count <> 0 Then WaitHandle.WaitAll(waitHandles3.ToArray())
    If waitHandles4.Count <> 0 Then WaitHandle.WaitAll(waitHandles4.ToArray())

    Thread.Sleep(1000)

End Sub

Modifier Le tableau est vide quand je le casse. Mais en quelque sorte quelque chose tourne encore. Peut-être que je manque attraper un.

Était-ce utile?

La solution

La quasi-totalité de la complexité de votre code peut être évité en utilisant la nouvelle

scroll top