Thread shutdown is a mechanism to stop a worker Thread that is already running in parallel. That means either to stop an already running thread using Thread.Abort
or shutting down the Thread normally using the user defined code.
Co-Ordinating
Thread Shutdown involves the way you co-ordinate the Shutdown
of a Worker thread from Main thread or any other worker thread such that the Thread terminates normally after it finishes the execution logic.
Lets describe this using code :
public static volatile bool CancelToken = false; static void Main(string[] args) { Console.WriteLine("Starting a New Thread "); Thread newThread = new Thread(Run); newThread.Name = "Worker Thread"; newThread.Start(); Console.WriteLine("Request close the Thread"); CancelToken = true; Console.WriteLine("Request made!"); newThread.Join(); Console.WriteLine("Thread Shutdown !"); Console.ReadKey(true); } static void Run() { while (!CancelToken) { Console.WriteLine("Running {0}!!!", Thread.CurrentThread.Name); Thread.Sleep(1000); } }
Here in the code, I have created a static volatile Boolean variable called CancelToken
which is used to cancel the execution of Run method
. In Main method, We started a new thread and called Run. This will start executing the logic written inside the Run method and will print “Running Worker Thread!!!” at an interval of 1 seconds. Once the CancelToken
is requested, it will go on executing until it reaches the while loop condition. The Thread Shutdown is co-ordinated from the Main thread using the static token.
Two things that you need to remember.
1. newThread.Join is required so that the current Thread remains blocked after the CancelToken
is set, such that it won’t print Thread Shutdown until the Worker Thread shuts down. If you don’t join the Thread, the Main Thread might shutdown before the Worker Thread finishes execution.
2. CancelToken is made volatile to ensure the while loop always reads the latest value from the Variable itself, rather than being smart to store it in cache registers.
Using CancellationTokenSource
:
You can also use CancellationTokenSource
class to do the same thing without using a Boolean volatile variable like before. Lets see the code below :
public static CancellationTokenSource CancelToken; static void Main(string[] args) { Console.WriteLine("Starting a New Thread "); CancelToken = new CancellationTokenSource(); Thread newThread = new Thread(new ParameterizedThreadStart(Run)); newThread.Name = "Worker Thread"; newThread.Start(CancelToken.Token); Console.WriteLine("Request close the Thread"); CancelToken.Cancel(); Console.WriteLine("Request made!"); newThread.Join(); CancelToken.Dispose(); Console.WriteLine("Thread Shutdown !"); Console.ReadKey(true); } static void Run(object cancelToken) { CancellationToken token = (CancellationToken)cancelToken; while (!token.IsCancellationRequested) { Console.WriteLine("Running {0}!!!", Thread.CurrentThread.Name); Thread.Sleep(1000); } }
The code works the same way, just it introduces a new object called CancellationTokenSource
which exposes a CancellationToken
from it. This has a volatile Boolean reference which is set to true when Cancel method is called from CancellationTokenSource
. Once Cancel is called, the CancellationToken.IsCancellationRequested
is set to true, and hence in our case the loop terminates.
I hope you like this post.
Thanks.
Pingback: Dew Drop – August 8, 2011 | Alvin Ashcraft's Morning Dew
Yes,
It seems good approach.