我正在研究一个程序,该程序扫描服务器列表以获取不同的信息。

一切正常,除非有时我会在线程完成后会出现错误。通过扫描完成或取消按钮停止循环,但让当前线程继续。

我看到UI说扫描已经完成,但是ProgressUpdate试图再次运行。我可以通过更长的线程解决问题来解决问题。

在大多数情况下,它等待了最后一个线程,但是有时我会遇到错误,说它无法访问ProgressUpdate函数,因为OperationsComplete已经运行了。

我在BackownWorker1.ReportProgress(_completedCount,scanresult)上遇到错误,但不应该这样称呼,因为Waitall应该等到线程完成。

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

当我打破它时,编辑阵列为空。但是某种程度上仍然有些事情。也许我错过了抓住一个。

有帮助吗?

解决方案

通过使用新的,几乎可以避免代码中的所有复杂性 平行 .NET 4中的方法。这将消除维护等待手的需求,并提供一种简单的机制,以限制最大线程数量的最大数量。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top