Waitgroups in Visual Basic .NET
Our first example demonstrates the use of a WaitGroup
to synchronize multiple threads. Here’s the full source code:
Imports System
Imports System.Threading
Imports System.Threading.Tasks
Module WaitGroupExample
' This is the function we'll run in every thread.
Sub Worker(id As Integer)
Console.WriteLine($"Worker {id} starting")
' Sleep to simulate an expensive task.
Thread.Sleep(1000)
Console.WriteLine($"Worker {id} done")
End Sub
Sub Main()
' This CountdownEvent is used to wait for all the
' threads launched here to finish.
Dim wg As New CountdownEvent(5)
' Launch several threads and increment the CountdownEvent
' counter for each.
For i As Integer = 1 To 5
' Wrap the worker call in a Task that makes sure to tell
' the CountdownEvent that this worker is done. This way the worker
' itself does not have to be aware of the concurrency primitives
' involved in its execution.
Task.Run(Sub()
Try
Worker(i)
Finally
wg.Signal()
End Try
End Sub)
Next
' Block until the CountdownEvent counter goes back to 0;
' all the workers notified they're done.
wg.Wait()
' Note that this approach has no straightforward way
' to propagate errors from workers. For more
' advanced use cases, consider using the
' Task.WhenAll method with error handling.
End Sub
End Module
To run the program, save it as WaitGroupExample.vb
and use the Visual Basic compiler:
$ vbc WaitGroupExample.vb
$ mono WaitGroupExample.exe
Worker 3 starting
Worker 1 starting
Worker 2 starting
Worker 5 starting
Worker 4 starting
Worker 3 done
Worker 1 done
Worker 2 done
Worker 5 done
Worker 4 done
The order of workers starting up and finishing is likely to be different for each invocation.
In this Visual Basic .NET example, we use a CountdownEvent
as an equivalent to Go’s WaitGroup
. The CountdownEvent
is initialized with the number of operations we want to wait for, and each operation signals the event when it’s done.
We use Task.Run
to start each worker in a separate thread, which is similar to launching goroutines in Go. The Try
/Finally
block ensures that the CountdownEvent
is signaled even if an exception occurs in the worker.
The wg.Wait()
call blocks until all workers have finished, just like in the Go example.
Note that Visual Basic .NET and the .NET Framework provide more advanced concurrency patterns, such as the Task Parallel Library, which might be more suitable for complex scenarios.