Imports System.Threading
Public Class SyncEvents
Private _newItemEvent As EventWaitHandle
Public ReadOnly Property NewItemEvent() As EventWaitHandle
Get
Return _newItemEvent
End Get
End Property
Private _exitThreadEvent As EventWaitHandle
Public ReadOnly Property ExitThreadEvent() As EventWaitHandle
Get
Return _exitThreadEvent
End Get
End Property
Private _eventArray As WaitHandle()
Public ReadOnly Property EventArray() As WaitHandle()
Get
Return _eventArray
End Get
End Property
Public Sub New()
_newItemEvent = New AutoResetEvent(False)
_exitThreadEvent = New ManualResetEvent(False)
_eventArray = New WaitHandle() {_newItemEvent, _exitThreadEvent}
End Sub
End Class
Public Class Producer
Private _queue As Queue(Of Integer)
Private _syncEvents As SyncEvents
Public Sub New(ByVal q As Queue(Of Integer), ByVal e As SyncEvents)
_queue = q
_syncEvents = e
End Sub
Public Sub ThreadRun()
Dim count As Integer = 0
Dim r As New Random()
While Not _syncEvents.ExitThreadEvent.WaitOne(0, False)
SyncLock DirectCast(_queue, ICollection).SyncRoot
While _queue.Count < 20
_queue.Enqueue(r.Next(0, 100))
_syncEvents.NewItemEvent.Set()
count += 1
End While
End SyncLock
End While
Console.WriteLine("Producer thread: produced {0} items", count)
End Sub
End Class
Public Class Consumer
Private _queue As Queue(Of Integer)
Private _syncEvents As SyncEvents
Public Sub New(ByVal q As Queue(Of Integer), ByVal e As SyncEvents)
_queue = q
_syncEvents = e
End Sub
Public Sub ThreadRun()
Dim count As Integer = 0
While WaitHandle.WaitAny(_syncEvents.EventArray) <> 1
SyncLock DirectCast(_queue, ICollection).SyncRoot
Dim item As Integer = _queue.Dequeue()
count += 1
End SyncLock
End While
Console.WriteLine("Consumer thread: consumed {0} items", count)
End Sub
End Class
Public Class Program
Private Shared Sub ShowQueueContents(ByVal q As Queue(Of Integer))
SyncLock DirectCast(q, ICollection).SyncRoot
For Each item As Integer In q
Console.Write("{0} ", item)
Next
End SyncLock
Console.WriteLine()
End Sub
Public Shared Sub Main()
Dim queue As New Queue(Of Integer)
Dim syncEvent As New SyncEvents()
Console.WriteLine("Configuring worker threads...")
Dim producer As New Producer(queue, syncEvent)
Dim cunsumer As New Consumer(queue, syncEvent)
Dim producerThread As New Thread(AddressOf producer.ThreadRun)
Dim consumerThread As New Thread(AddressOf cunsumer.ThreadRun)
Console.WriteLine("Launching producer and consumer threads...")
producerThread.Start()
consumerThread.Start()
For i As Integer = 0 To 3
Thread.Sleep(2500)
ShowQueueContents(queue)
Next i
Console.WriteLine("Signaling threadds to terminate...")
syncEvent.ExitThreadEvent.Set()
producerThread.Join()
consumerThread.Join()
End Sub
End Class