Imports System.Threading Public Class MyThreadClass Public ThreadName As String = "" Public ThreadOutput As String = "" Public ThreadOutputFinal As String = "" Public RunningThreads As Integer = 0 Public ThreadInitComplete As Boolean = True Public Event DoThreadOutput(ByVal ThreadOutput As String) Public Event DoThreadComplete(ByVal ThreadOutputFinal As String) Public Sub ThreadLogic() Dim mThreadName As String SyncLock GetType(MyThreadClass) RunningThreads += 1 mThreadName = ThreadName ThreadInitComplete = True End SyncLock Dim j As Integer Dim ThreadDelay As Integer For j = 1 To 5 Randomize() ThreadDelay = Rnd() * 10000 Thread.Sleep(ThreadDelay) ThreadOutput = mThreadName + " Loop " + j.ToString + " Slept for " + ThreadDelay.ToString + "ms. Running threads " + RunningThreads.ToString RaiseEvent DoThreadOutput(ThreadOutput) Next SyncLock GetType(MyThreadClass) RaiseEvent DoThreadComplete(mThreadName + " Complete") RunningThreads -= 1 End SyncLock End Sub End Class Module Module1 Dim WithEvents oThread As New MyThreadClass Sub Main() Dim t As Thread For i As Integer = 1 To 10 Dim StartTime As DateTime StartTime = DateTime.Now While Not oThread.ThreadInitComplete Thread.Sleep(100) If DateTime.Now.Subtract(StartTime).Seconds > 120 Then 'Continue if thread doesn't init in 120 seconds oThread.ThreadInitComplete = True End If End While t = New Thread(AddressOf oThread.ThreadLogic) SyncLock GetType(Module1) oThread.ThreadName = "Thread " + i.ToString oThread.ThreadInitComplete = False t.Start() End SyncLock Next Do While oThread.RunningThreads > 0 Thread.Sleep(250) Loop MsgBox("Done") End Sub Sub DoThreadOutput(ByVal ThreadOutput As String) Handles oThread.DoThreadOutput Console.WriteLine(ThreadOutput) End Sub Sub DoThreadComplete(ByVal ThreadOutputFinal As String) Handles oThread.DoThreadComplete Console.WriteLine(ThreadOutputFinal) End Sub End Module