Thread Class in C#


System.Threading.Thread Class in C#

A thread is an execution path in Application Domain. System.Threading.Thread is the main class used to create, control and prioritize threads in an application domain.

Some of the key Instance level members of Threading.Thread class are listed in the below table.

Member

Description

Name

 This property of string type is used to get or set the friendly name that the developer can identify with.

Priority

This property is used to get or set the thread's scheduling priority. The property can have a value among the following AboveNormal, BelowNormal, Normal, Highest and Lowest.

IsAlive

A Boolean property which indicates whether a thread is alive or terminated.

IsBackground 

This property is used to set/get the thread type (Background or Foreground)

Start()

Starts the execution of the thread

Abort()

Allows the thread to stop execution permanently. The thread throws a ThreadAbortException.

Suspend()

Pauses the execution of a thread temporarily

Resume()

Resumes the execution of a suspended thread.

Join()

Makes the current thread wait for another thread (The thread object on which join is called) to finish.

ThreadState

This property is used to determine the property containing the state of the thread. The value returned by the property is one among the following - Aborted, AbortRequested, Suspended, Stopped, Unstarted, Wait, Sleep, Join etc.


Some of the Static members of Threading.Thread class are listed in the below table.

Member

Description

CurrentThread

Gets a reference to the currently running thread.

CurrentContext

Gets a reference to the context in which current thread is running.

GetDomain

Gets a reference to the current application domain.

Sleep

Suspends a current thread for specific time.

 

Priority Property

The default priority level of the Thread is ThreadPriority.Normal. You can change the priority to one of the options in the below enum.

    public enum ThreadPriority
    {
        Lowest,
        BelowNormal,
        Normal, // Default value.
        AboveNormal,
        Highest
    }

As a programmer you do not have any control on thread scheduling, Thread priority is just a hint to the CLR about the importance of threads activity. Hence, ThreadPriority.Highest doesn’t assure that the thread is given highest precedence by thread scheduler.
 

Thread Class Constructors

Signature

Description

Thread(ParameterizedThreadStart)

Initializes a Thread object. It takes ParameterizedThreadStart delegate as input. This delegate takes input parameter if type object and returns void.

Thread(ParameterizedThreadStart, Int32)

Same as above. It has maximum stack size of thread as additional input parameter.

Thread(ThreadStart)

Initialized thread object. It takes ThreadStart delegate as input. This delegate has no parameters and returns void.

Thread(ThreadStart, Int32)

Same as above. It has maximum stack size of thread as additional input parameter.

 

When a thread is created you have to specify the entry method to the new thread object. Entry method can be of two signatures

  1. A method without any parameters and return type void. ThreadStart delegate supported constructors take these methods as entry point.
  2. A method with only one input parameter of type object and return type void. ParameterizedThreadStart delegate supported constructors take these methods as entry point.

 

Steps involved in Creating and Using Secondary Threads

  1. Define a new method to be entry point.
  2. Create ParameterizedThreadStart/ ThreadStart delegate object and pass address of the method in step 1 to the constructor.
  3. Create a Thread by passing the delegate created in the step 2 to the constructor.
  4. Set the thread properties (like Priority, Name etc.)
  5. Start the Thread, the execution starts at the method pointed by the delegate.

 

Create Thread with ThreadStart Delegate

ThreadStart delegate can point to a method that return void and take no parameters. In the below example PrintInformation static method is pointed to ThreadStart delegate.

using System;
using System.Threading;
using System.Collections.Generic;

namespace CSharp_Samples
{
    public class ThreadSamples
    {
        /// <summary>
        /// Waits for 2 seconds and Prints the thread ID.
        /// </summary>
        public static void PrintInformation()
        {
            Thread.Sleep(2000);
            Console.WriteLine("Thread Id = {0}", Thread.CurrentThread.Name);
        }
       
        public static void Main()
        {
            // Create a thread and point to a method without parameters using ThreadStart Delegate.
            Thread threadStartWithoutParameters = new Thread(new ThreadStart(PrintInformation));

            // Set the thread name.
            threadStartWithoutParameters.Name = "ThreadStartWithoutParameters";

            // Start the Thread.
            threadStartWithoutParameters.Start();

            // Do your work here.
            Console.WriteLine("Main Thread[{0}] working...", Thread.CurrentThread.Name);
            
            // Once finished, wait for thread to complete its work.
            threadStartWithoutParameters.Join();

        }
    }
}

Create Thread with ParameterizedThreadStart Delegate

ParameterizedThreadStart can point to a method that return void and takes only one parameter of type object. In the below example address of AddNumbers instance method of ClassNumbers object is pointed to ParameterizedThreadStart delegate.

using System;
using System.Threading;
using System.Collections.Generic;

namespace CSharp_Samples
{
    public class ClassNumbers
    {
        /// <summary>
        /// Waits for 2 seconds, adds numbers and displays count.
        /// </summary>
        /// <param name="obj"></param>
        public void AddNumbers(object obj)
        {
            // Cast the input to List<int>
            List<int> numbers = obj as List<int>;

            // If cast failed, print error.
            if (obj == null)
            {
                Console.WriteLine("Invalid Input.");
            }
            else
            {
                // Print the status.
                Console.WriteLine("Thread[{0}] is adding numbers.", Thread.CurrentThread.Name);

                // Sleep for two seconds.
                Thread.Sleep(2000);
                int result = 0;

                // Add numbers.
                foreach (int number in numbers)
                {
                    result += number;
                }

                // Print result
                Console.WriteLine("Total is {0}", result);
            }

        }
    }

    public class ThreadSamples
    {
        public static void Main()
        {
            // Initialize ClassNumbers object.
            // We will use AddNumbers as entry point.
            ClassNumbers classNumbers = new ClassNumbers();

            // Initiliaze a List if ints.
            // We will pass this as input to AddNumbers.
            List<int> numbers = new List<int>(){10, 3, 68, 55, 77, 34};

            // Create a thread and point to a method with object type as parameter using ParameterizedThreadStart Delegate.
            Thread threadStartWithParameters = new Thread(new ParameterizedThreadStart(classNumbers.AddNumbers));

            // Set the thread name.
            threadStartWithParameters.Name = "ThreadStartWithParameters";

            // Start the work.
            threadStartWithParameters.Start(numbers);

            // Do your work here.
            Console.WriteLine("Main Thread[{0}] working...", Thread.CurrentThread.Name);

            // Once finished, wait for thread to complete its work.
            threadStartWithParameters.Join();
        }
    }
}