Thread.abort висит навсегда
Код для запуска запроса wmi на удаленных компьютерах. Этот код выполняется в нескольких потоках одновременно.
oquery = New ManagementObjectSearcher("select * from Win32_Computersystem")
oquery.Options.ReturnImmediately = True
oquery.Options.Rewindable = False
oquery.Options.Timeout = New TimeSpan(0, 8, 0)
oquery.Scope = mycomputer.omsWMI 'timeout of omswmi is set to (0,1,0)
For Each objMgmt In oquery.Get 'on some pesky windows XP machines this line hangs forever regardless of the timeout and the thread can never be used to get info from another computer. the only way to "release" this is to reboot the target computer.
'do stuff
next
Код работает в основном потоке:
Public Sub KillLongRunningThreads()
Dim tel As Integer
SyncLock LockMythreadlist
For tel = MyThreadlist.Count - 1 To 0 Step -1
If CType(MyThreadlist(tel), wmithread).Starttime < Now.AddMinutes(-120) Then
DBG("INFO: before threadabort")
Try
'this line tries to abort the first thread but is also hanging forever, the INFO:after threadabort is never reached.
'even worse this line hangs in the middle of a synclock which causes the program to stop working (all other threads are waiting for the end syncklock.
CType(MyThreadlist(tel), wmithread).TheThread.Abort()
Catch ex As Exception
DBG(ex.Message & ex.StackTrace)
End Try
DBG("INFO: after threadabort")
MyThreadlist.RemoveAt(tel)
End If
Next
End SyncLock
End sub
Два вопроса:
Как остановить первый поток?
Как остановить первый поток и не создать тупик?
1 ответ
В документации по Thread.Abort:
f Прерывание вызывается в управляемом потоке, когда он выполняет неуправляемый код, исключение ThreadAbortException не генерируется, пока поток не вернется в управляемый код.
Поскольку ваш поток, кажется, зависает в неуправляемом коде, прерывание управляемого потока ничего не сделает.
Я понятия не имею, как предотвратить зависание потока в запросе WMI или как отменить зависший запрос WMI.