Pass Parameters to Threads with a Class
The trick is to start the thread in the context of a class that already has the parameter values you want to send. Rather than launching the new thread directly from the btnLaunchThread_Click
event, you create a new class that has properties to hold the ThreadStart delegate and the number of counter iterations.
|Figure 1: This process flow diagram shows the sequence to launch a thread using a separate class to pass parameters. The main form thread (which runs the UI) is essentially unaffected by the new thread.|
The CounterArgs class serves that purpose. The public iterations
field holds the number of counter iterations, and the startDelegate
field holds a StartCounterDelegate, which is a pre-created delegate that matches the Count()
method in the form. The class has one method, StartCounting()
, which calls the method represented by the StartCounterDelegate (the Count()
method) and passes the number of iterations. In other words, to launch a new thread and pass the number of iterations, you create a new CounterArgs class, set its Iterations property, and then create a new StartCounterDelegate which represents the Count()
method. Finally, you create a new Thread with a ThreadStart delegate that represents the CounterArgs.StartCounting
method. When you start the new thread, it runs in the CounterArgs class, and therefore it has access to the values of the Iterations and StartDelegate fields. Figure 1
shows the process.
Here's the complete code for the CounterArgs class.
Private Class CounterArgs
Public Iterations As Integer
Public StartDelegate As StartCounterDelegate
Public Sub StartCounting()
The remaining code is simple: create a Count method that accepts the number of iterations to count.
Public Sub Count(ByVal iterations As Integer)
Dim i As Integer
For i = 0 To iterations
Console.WriteLine(Thread.CurrentThread.Name & _
": " & i.ToString)
When you click the button on Form 1
, the thread starts and writes the expected outputand if you click the button several times, you'll see the correct output for each thread.
Private Sub btnLaunchThread_Click( _
ByVal sender As System.Object, _
ByVal e As System.EventArgs) _
Dim iterations As Integer
iterations = CInt(Me.txtIterations.Text)
Catch ex As System.InvalidCastException
Dim ca As New CounterArgs()
ca.Iterations = iterations
ca.StartDelegate = AddressOf Count
Dim t As New Thread(AddressOf ca.StartCounting)
threadCount += 1
t.Name = "Thread " & threadCount.ToString()
Console.WriteLine("starting thread " & _
t.Name & " to count " & iterations & _
t.IsBackground = True