Как ждать, пока все рабочие потоки в threadPools не исчезнут - PullRequest
0 голосов
/ 23 января 2012

Кто-нибудь знает простой способ сделать это?

По существу, после того, как я поставил все работы в очередь, я хочу подождать, пока все мои очереди не будут выполнены. Как мне это сделать?

   loopThroughAllBlog(whattodo, login)'queue all works

// что делать здесь, чтобы дождаться завершения всех работ в очереди.

    Dim whatToWrite = New Generic.List(Of String)
    For Each domain In domainsSorted
        whatToWrite.Add(dictionaryOfOutput.Item(domain))
    Next
    coltofile(whatToWrite, "output.txt", True)

Я заметил, что нет способа узнать, сколько потоков все еще работает в пуле потоков.

Ответы [ 2 ]

4 голосов
/ 23 января 2012

Распространенным способом достижения этого является использование счетчика, защищенного семафором. (Мне кажется, ваш код VB. Я не знаю VB, поэтому мой синтаксис, вероятно, отключен, рассматривайте его как псевдокод).

Сначала вам нужно настроить семафор и счетчик:

' a semaphore is a counter, you decrease it with WaitOne() and increase with Release()
' if the value is 0, the thread is blocked until someone calls Release()
Dim lock = new Semaphore(0, 1)
Dim threadcount = 10 ' or whatever

В конце функции, выполняемой пулом потоков, необходимо уменьшить счетчик потоков и снять блокировку, если число потоков равно 0

threadcount = threadcount - 1
if threadcount = 0 then
    lock.Release()
end if

во время ожидания ваших потоков попробуйте получить семафор, который будет блокироваться до тех пор, пока кто-то не вызовет release:

lock.WaitOne()

для операции уменьшения и проверки, описанной выше, вы, вероятно, захотите поместить это в отдельную подпрограмму. Вам также необходимо защитить это, чтобы каждый поток, который пытается получить доступ к счетчику, был изолирован от других потоков.

dim counterMutex = new Mutex()
sub decreaseThreadCount()
    counterMutex.WaitOne()
    threadcount = threadcount - 1
    if threadcount = 0 then
        lock.Release()
    end if
    counterMutex.release()
end sub
0 голосов
/ 23 января 2012

Я закончил тем, что отвечал на свой вопрос, потому что ответа нет.

Public Function threadPoolIdle() As Boolean
    Dim workerThreads As Integer
    Dim completionPorts As Integer
    Dim maxWorkerThreads As Integer
    Dim maxCompletionPorts As Integer
    Dim stillWorking As Integer

    Threading.ThreadPool.GetAvailableThreads(workerThreads, completionPorts)
    Threading.ThreadPool.GetMaxThreads(maxWorkerThreads, maxCompletionPorts)
    stillWorking = maxWorkerThreads + maxCompletionPorts - workerThreads - completionPorts

    If stillWorking > 0 Then
        Return False
    Else
        Return True
    End If

End Function

Public Sub waitTillThreadPoolisIdle()
    Do
        Sleep(1000)
        Application.DoEvents()
    Loop While threadPoolIdle() = False
End Sub

Я думаю, что это просто неловко.Должен быть лучший способ.

...