Range Over Channels in Visual Basic .NET
In a previous example, we saw how For Each
provides iteration over basic data structures. We can also use this syntax to iterate over values received from a queue.
Imports System
Imports System.Collections.Concurrent
Module Program
Sub Main()
' We'll iterate over 2 values in the queue.
Dim queue As New BlockingCollection(Of String)(2)
queue.Add("one")
queue.Add("two")
queue.CompleteAdding()
' This For Each iterates over each element as it's
' received from queue. Because we called CompleteAdding
' on the queue above, the iteration terminates after
' receiving the 2 elements.
For Each elem In queue.GetConsumingEnumerable()
Console.WriteLine(elem)
Next
End Sub
End Module
To run the program:
$ vbc range-over-channels.vb
$ mono range-over-channels.exe
one
two
This example also showed that it’s possible to complete adding to a non-empty collection but still have the remaining values be received.
In Visual Basic .NET, we use BlockingCollection(Of T)
as an equivalent to Go’s buffered channels. The CompleteAdding()
method serves a similar purpose to Go’s close()
for channels. The GetConsumingEnumerable()
method allows us to iterate over the items in the collection as they become available, similar to ranging over a channel in Go.
The For Each
loop in VB.NET provides similar functionality to Go’s for range
loop when used with the GetConsumingEnumerable()
method of a BlockingCollection
. It will iterate over the elements in the collection, blocking if necessary until an item is available, and will exit when the collection is empty and completed.