我是线程新手,并通过手动启动myThread.Start()
的线程开始。我完成了所有工作,除非关闭状态表单,结束的第一个线程将关闭表单而不是最后一个。所以我决定尝试使用QueueUserWorkItem
和handle.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