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 ModuleTo run the program:
$ vbc range-over-channels.vb
$ mono range-over-channels.exe
one
twoThis 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.