Me.Invoke(Delegate)挂起应用程序

时间:2014-09-21 17:32:05

标签: vb.net multithreading threadpool invoke

我是线程新手,并通过手动启动myThread.Start()的线程开始。我完成了所有工作,除非关闭状态表单,结束的第一个线程将关闭表单而不是最后一个。所以我决定尝试使用QueueUserWorkItemhandle.waitOne()的循环。

现在突然,应用程序在调用Me.Invoke(disposal)时开始挂起 - 在Public Sub wol_SearchCompleted()中。奇怪的是,有时我会逐步完成代码,它会挂在那条线上,有时它会完美运行。

Public Class frmMain

Private wolActiveThreads(Environment.ProcessorCount - 1) As ManualResetEvent 'I have tried setting this to wolActiveThreads(1) but there is no difference
Private adActiveThreads(Environment.ProcessorCount - 1) As ManualResetEvent

Private Sub GetMacAddresses(ByVal compCollection As ComputerCollection)
    If compCollection.Count = 0 Then Exit Sub

    'Work out how many threads to use and how many computers each thread will discover
    Dim numThreads As Integer = wolActiveThreads.Count - 1
    Dim remainder As Double = compCollection.Count Mod numThreads
    Dim numPerThread As Double = (compCollection.Count - remainder) / numThreads

    'Start the threads
    For i As Integer = 0 To numThreads - 1
        Dim startIndex As Integer = (i * numPerThread)
        Dim endIndex As Integer = startIndex + (numPerThread - 1)

        IIf(i = numThreads - 1, endIndex = endIndex + remainder, endIndex = endIndex) 'If this is the last thread add the remainder of computers which didn't devide equally

        Dim threadParams As Object
        threadParams = New Object() {compCollection, startIndex, endIndex} 'Create an object to pass the parameters

        Dim n As Integer = i
        wolInstances(n) = New WOL(wolActiveThreads(n))
        ThreadPool.QueueUserWorkItem(New WaitCallback(AddressOf wolInstances(n).StartMACSearch), threadParams)

    Next

    'If the status dialog isn't displayed, display it
    If statusDialog Is Nothing Then
        statusDialog = New frmStatus
        statusDialog.ShowDialog()
    End If

End Sub

Private Sub StatusDialogDisposal()

    'Wait for all of the ADSearcher class threads to finish
    For Each handle As WaitHandle In adActiveThreads
        handle.WaitOne()
    Next
    'Wait for all of the WOL class threads to finish
    For Each handle As WaitHandle In wolActiveThreads
        handle.WaitOne()
    Next

    If statusDialog IsNot Nothing Then 'If another thread hasn't already disposed of the dialog
        statusDialog.Close() 'Close the dialog
        statusDialog.Dispose() 'Dispose of the dialog
        statusDialog = Nothing 'Dereference the diposed dialog to prevent errors
    End If

End Sub

'[WOL Events]
Private Delegate Sub disposeStatus()
Public Sub wol_SearchCompleted()
    Dim disposal As New disposeStatus(AddressOf StatusDialogDisposal)
    Me.Invoke(disposal)
End Sub

类别:

Public Class WOL

Public Sub New(ByVal doneEvent As ManualResetEvent)

    'Add event handlers
    AddHandler Me.MACAddressFound, AddressOf frmMain.wol_MACAddressFound
    AddHandler Me.SearchCompleted, AddressOf frmMain.wol_SearchCompleted

    _doneEvent = doneEvent

End Sub

Public Sub StartMACSearch(ByVal parameters As Object)
    _doneEvent.Reset() 'Make sure the thread pool knows the thread is still working

    Dim computerList As ComputerCollection = parameters(0)
    Dim startIndex As Integer = parameters(1)
    Dim endIndex As Integer = parameters(2)

    macsFound = 0

    For i As Integer = startIndex To endIndex
        GetMACAddress(computerList(i).FQDN)
    Next

    System.Diagnostics.Debug.Print("Thread " + startIndex.ToString + " to " + endIndex.ToString + " is ending")

    RaiseEvent SearchCompleted()
    _doneEvent.Set() 'Signal that the thread is finished

End Sub

End Class

0 个答案:

没有答案