Finally, to stop the thread in the Main()
function, you just need to set the _stopThread
variable to true
:
_stopThread = true;
Console.WriteLine('Thread ended.');
The output of this program
Continuing with the execution.
Doing something...
Doing something...
Doing something...
Doing something...
Doing something...
Doing something...
Thread ended.
Doing something...
The DoSomething()
function may print another message after the 'Thread ended.
' message. That's because the thread might not end immediately. To ensure that the 'Thread ended.
' message is printed only after the DoSomething()
function ends, you can use the Join()
method of the Thread
class to join the two threads:
static void Main(string[] args) {
Thread t = new Thread(new ThreadStart(DoSomething));
t.Start();
Console.WriteLine('Continuing with the execution...');
while (!t.IsAlive);
Thread.Sleep(1);
_stopThread = true;
//---joins the current thread (Main()) to t---
t.Join();
Console.WriteLine('Thread ended.');
Console.ReadLine();
}
The Join()
method essentially blocks the calling thread until the thread terminates. In this case, the Thread
ended message will be blocked until the thread (t
) terminates.
The output of the program now looks like this:
Continuing with the execution.
Doing something...
Doing something...
Doing something...
Doing something...
Doing something...
Doing something...
Thread ended.
Figure 10-4 shows graphically the two different threads of execution.

Figure 10-4
Passing Parameters to Threads
In the past few examples, you've seen how to create a thread using the ThreadStart
delegate to point to a method. So far, though, the method that you have been pointing to does not have any parameters:
static void DoSomething() {
...
...
}
What if the function you want to invoke as a thread has a parameter? In that case, you have two choices:
□ Wrap the function inside a class, and pass in the parameter via a property.
□ Use the ParameterizedThreadStart
delegate instead of the ThreadStart
delegate.
Using the same example, the first choice is to wrap the DoSomething() method as a class and then expose a property to take in the parameter value:
class Program {
static void Main(string[] args) {
Thread t = new Thread(new ThreadStart(sc.DoSomething));
t.Start();
}
}
class SomeClass {
public void DoSomething() {
try {
while (true) {
Console.WriteLine('Doing something...{0}', msg);
}
} catch (ThreadAbortException ex) {
Console.WriteLine(ex.Message);
} finally {
//---clean up your resources here---
}
}
}
In this example, you create a thread for the DoSomething()
method by creating a new instance of the SomeClass
class and then passing in the value through the msg property.
For the second choice, you use the ParameterizedThreadStart
delegate instead of the ThreadStart
delegate. The ParameterizedThreadStart
delegate takes a parameter of type object, so if the function that you want to invoke as a thread has a parameter, that parameter must be of type object
.
To see how to use the ParameterizedThreadStart
delegate, modify the DoSomething()
function by adding a parameter:
try {
while (true) {