Title here
Summary here
In this example we’ll look at how to implement a worker pool using threads and queues.
Imports System
Imports System.Threading
Imports System.Collections.Concurrent
Module WorkerPools
' Here's the worker, of which we'll run several
' concurrent instances. These workers will receive
' work on the `jobs` queue and send the corresponding
' results on `results`. We'll sleep a second per job to
' simulate an expensive task.
Sub Worker(id As Integer, jobs As BlockingCollection(Of Integer), results As BlockingCollection(Of Integer))
For Each j In jobs.GetConsumingEnumerable()
Console.WriteLine($"worker {id} started job {j}")
Thread.Sleep(1000)
Console.WriteLine($"worker {id} finished job {j}")
results.Add(j * 2)
Next
End Sub
Sub Main()
' In order to use our pool of workers we need to send
' them work and collect their results. We make 2
' queues for this.
Const numJobs As Integer = 5
Dim jobs As New BlockingCollection(Of Integer)(numJobs)
Dim results As New BlockingCollection(Of Integer)(numJobs)
' This starts up 3 workers, initially blocked
' because there are no jobs yet.
For w As Integer = 1 To 3
Dim workerID As Integer = w
Dim thread As New Thread(Sub() Worker(workerID, jobs, results))
thread.Start()
Next
' Here we send 5 `jobs` and then `close` that
' queue to indicate that's all the work we have.
For j As Integer = 1 To numJobs
jobs.Add(j)
Next
jobs.CompleteAdding()
' Finally we collect all the results of the work.
' This also ensures that the worker threads have
' finished. An alternative way to wait for multiple
' threads is to use Thread.Join().
For a As Integer = 1 To numJobs
results.Take()
Next
End Sub
End Module
Our running program shows the 5 jobs being executed by various workers. The program only takes about 2 seconds despite doing about 5 seconds of total work because there are 3 workers operating concurrently.
$ vbc WorkerPools.vb
$ mono WorkerPools.exe
worker 1 started job 1
worker 3 started job 3
worker 2 started job 2
worker 1 finished job 1
worker 1 started job 4
worker 3 finished job 3
worker 2 finished job 2
worker 2 started job 5
worker 1 finished job 4
worker 2 finished job 5
real 0m2.358s
In this Visual Basic .NET version:
Thread
instead of goroutines for concurrency.BlockingCollection(Of T)
is used in place of channels for thread-safe communication between threads.Worker
function is defined as a Sub
that takes a BlockingCollection(Of Integer)
for both jobs and results.Thread.Sleep(1000)
to simulate work instead of time.Sleep(time.Second)
.Thread
instances and starts them.jobs.CompleteAdding()
to signal that no more items will be added to the jobs collection.results.Take()
which blocks until an item is available.This implementation maintains the core concept of the worker pool pattern, demonstrating how to distribute work across multiple threads and collect results in Visual Basic .NET.