C# Thread (Threading)

In c#, thread is a basic unit of execution within the process and it is responsible for executing the application logic.

 

By default, every application or program will carry one thread to execute the application logic and that thread is called a Main thread. So, we can say that every program or application is by default a single threaded model.

 

For example, in windows operating system if we open Microsoft Excel and Word applications simultaneously, then each application process will be taken care by separate threads.

 

In c#, we need to import System.Threading namespace in our program to work with threads. Once we import System.Threading namespace, we can create or access the threads using Thread class.

 

Generally, in c# when we start a program execution, the Main thread will automatically create to handle the program logic. If we create any other threads in our program by using Thread class those will become a child threads for the Main thread.

C# Access Main Thread

If we want to access the Main thread that is executing the current program code, we can get it by using CurrentThread property of the Thread class.

 

Following is the example of getting the main thread details using CurrentThread property of Thread class.

 

using System;

using System.Threading;

 

namespace TutlaneExamples

{

    class Program

    {

        static void Main(string[] args)

        {

            Thread t1 = Thread.CurrentThread;

            Console.WriteLine("Thread Id:{0}", t1.ManagedThreadId);

            Console.WriteLine("Is Background Thread:{0}", t1.IsBackground);

            Console.WriteLine("Thread Culture:{0}", t1.CurrentCulture);

            Console.ReadLine();

        }

    }

}

If you observe the above code, we imported System.Threading namespace to get the main thread details by using CurrentThread property of Thread class.

 

When we execute the above program, we will get the result like as shown below.

 

Thread Id:10

Is Background Thread:False

Thread Culture:en-IN

This is how we can access the main thread of our application which executing our program code based on our requirements.

 

In c#, the Main thread is responsible for executing the programming logic in a synchronous way that means one after another. In case, if we want to execute the few tasks simultaneously (asynchronous way), then we need to create the child threads in our application.

C# Create Thread

In c#, we can create a thread by extending the Thread class. To create a new thread, we need to pass ThreadStart delegate as a parameter to the Thread constructor like as shown below. Here, the parameter of ThreadStart is the method that will be executed by the new thread.

 

Once the thread is created, we need to call the Start method of Thread class to start the execution of the newly created thread.

 

// Create thread

Thread t1 = new Thread(new ThreadStart(PrintInfo));

// start newly created thread

t1.Start();

Here, PrintInfo is the method and it will be executed when we start the newly created thread. Initially, when we create a thread that will in the unstarted state, so we need to start the thread by using Start() method.

 

As we discussed if we create any threads in our program by using Thread class those will become a child threads for the Main thread.

 

Following is the example of creating the thread in c# using Thread class.

 

using System;

using System.Threading;

 

namespace TutlaneExamples

{

    class Program

    {

        static void Main(string[] args)

        {

            // Create child thread

            Thread t1 = new Thread(new ThreadStart(PrintInfo));

            // start newly created thread

            t1.Start();

            Console.WriteLine("Main Thread Completed");

            Console.ReadLine();

        }

        static void PrintInfo()

        {

            for (int i = 1; i <= 4; i++)

            {

                Console.WriteLine("i value: {0}", i);

            }

            Console.WriteLine("Child Thread Completed");

        }

    }

}

When we execute the above program, we will get the result like as shown below.

 

Main Thread Completed

i value: 1

i value: 2

i value: 3

i value: 4

Child Thread Completed

If you observe the above result, the Main thread and child thread started its execution simultaneously and child thread continued its execution till it finishes its task even after completion of Main thread execution.

C# Thread Properties

Following table lists some of the most commonly used properties of Thread class to work with threads in c#.

 

PropertyDescription
CurrentContext It will return the current context in which the thread is executing.
CurrentThread It will return the currently running thread.
CurrentCulture It is useful to get or set the culture for current thread.
CurrentUICulture It is useful to get or set the Resource Manager current culture to look up culture-specific resources at run time.
IsAlive It is useful to get the execution status of current thread.
IsBackground It is useful to get or set a value which indicating whether the thread is background thread or not.
IsThreadPoolThread It will return a value which indicate whether the thread belongs to the managed thread pool or not.
ManagedThreadId It will return unique identifier of the current managed thread.
Name It is useful to get or set the name of the thread.
Priority We can get or set a value which indicate the schedule priority of a thread.
ThreadState It is useful to get the state of current thread.

C# Thread Methods

Following table lists some of the most commonly used methods of Thread class to work with threads in c#.

 

MethodDescription
Abort() This method is useful to terminate the thread.
AllocateDataSlot() It will allocates an unnamed data slot on all the threads.
AllocateNamedDataSlot() It will allocates a named data slot on all threads.
BeginThreadAffinity() It will notify a host that the managed code is about to execute the instructions that depend on the identity of current physical operating system thread.
EndThreadAffinity() It will notify a host that the managed code has finished executing the instructions that depend on the identity of the current physical operating system thread.
Equals() It will determine whether the specified object is equal to the current object or not.
Finalize() It will ensures that the resources are freed and other cleanup operations are performed when the garbage collector reclaims the Thread object.
GetData() It is useful to retrieve the value from the specified slot on the current thread.
GetDomain() It will return the current domain in which the current thread is running.
GetHashCode() It will return the hash code of current thread.
GetType() It will return the type of current instance.
Interrupt() It will interrupt a thread that is in the WaitSleepJoin thread state.
Join() It will make the thread to finish its work or it will halt other threads until it finishes work.
Resume() It will resumes a thread that has been suspended.
Sleep() It will suspend the current thread for specified amount of time.
Start() It will instruct the operating system to change the state of current instance to Running.
Suspend() It will suspend the thread.
VolatileRead() It will read the value of a field and that value is the latest written by any processor in a computer.
VolatileWrite() It will write a value to the field immediately, so that the value will be visible for all processors in the computer.
Yield() It will yield the execution to another thread that is ready to run on the current processor.

C# Thread Life Cycle

In c#, each thread will have a life cycle and it will start when we create an instance of object using Thread class. Once the task execution of thread is completed, then the life cycle of thread will get end.

 

At any point of time, the thread in c# will exists in any one of the following states.

 

StateDescription
Unstarted When we create the thread that will be in unstarted state.
Runnable When we call the Start() method, the thread will be moved to ready to run or runnable state.
Running It indicates that the thread is in running state.
Not Runnable If thread is in not runnable state means there is a chance that the Sleep() or Wait() or Suspend() method is called on the thread or blocked by I/O operations.
Dead If thread is in dead state means the thread completes its task execution or it is aborted.

Following is the example of knowing the lifecycle and states of thread in c#.

 

using System;

using System.Threading;

 

namespace TutlaneExamples

{

    class Program

    {

        static void Main(string[] args)

        {

            // Create child thread

            Thread t1 = new Thread(new ThreadStart(PrintInfo));

            Console.WriteLine("Thread State: {0}", t1.ThreadState);

            // Start newly created thread

            t1.Start();

            Console.WriteLine("Thread State: {0}", t1.ThreadState);

            // Suspend thread

            t1.Suspend();

            Console.WriteLine("Thread State: {0}", t1.ThreadState);

            // Resume thread to running state

            t1.Resume();

            Console.WriteLine("Thread State: {0}", t1.ThreadState);

            Console.ReadLine();

        }

        static void PrintInfo()

        {

            Console.WriteLine("Method Execution");

        }

    }

}

If you observe the above example, we used ThreadState property of Thread class to know the state of thread and we used Start(), Suspend(), and Resume() methods of Thread class to start, suspend and resume the execution of thread.

 

When we execute the above program, we will get the result like as shown below.

 

Thread State: Unstarted

Thread State: Running

Thread State: Suspended

Thread State: Running

Method Execution

This is how we can change or vary the thread states in our application based on requirements.

C# Thread Example

Following is the example of managing the thread by using various methods of Thread class.

 

using System;

using System.Diagnostics;

using System.Threading;

 

namespace TutlaneExamples

{

    class Program

    {

        static void Main(string[] args)

        {

            Stopwatch sw = new Stopwatch();

            sw.Start();

            Thread t1 = new Thread(new ThreadStart(PrintInfo));

            t1.Start();

            t1.Join(); // Halt the execution till thread execution completed

            sw.Stop();

            TimeSpan ts = sw.Elapsed;

            string et = String.Format("{0}:{1}:{2}", ts.Hours, ts.Minutes, ts.Seconds);

            Console.WriteLine("TotalTime " + et);

            Console.WriteLine("Thread Execution Completed");

            Console.ReadLine();

        }

        static void PrintInfo()

        {

            for (int i = 1; i <= 5; i++)

            {

                Console.WriteLine("Thread paused for {0} seconds", 4);

                Thread.Sleep(4000); // Make Thread Pause for 4 Seconds

                Console.WriteLine("i value: {0}", i);

            }

        }

    }

}

If you observe the above example, we used different methods (Start, Join, and Sleep) of Thread class to manage the thread and the Stopwatch functionality is used to calculate the thread execution time based on our requirements.

 

Here, we used Start() method to start the thread execution, Join() method to halt the execution till the thread execution completed and the Sleep() method is used to pause the thread execution for 4 seconds.

 

When we execute the above program, we will get the result like as shown below.

 

Thread paused for 4 seconds

i value: 1

Thread paused for 4 seconds

i value: 2

Thread paused for 4 seconds

i value: 3

Thread paused for 4 seconds

i value: 4

Thread paused for 4 seconds

i value: 5

TotalTime 0:0:20

Thread Execution Completed

This is we can manage the thread execution by using Thread class methods based on our requirements.

C# Destroy or Abort Thread

In c#, by using Abort() method of Thread class we can end or abort the thread execution process. While terminating the thread process, the Abort() method will raise a ThreadAbortException in the thread on which it is invoked.

 

Following is the example of terminating the thread execution process in c#.

 

Thread t1 = new Thread(new ThreadStart(PrintInfo));

t1.Start();

t1.Join();

 

t1.Abort()

C# Thread Types

In c#, we have two types of threads are available, those are

 

  • Foreground Threads
  • Background Threads

C# Foreground Threads

As we discussed, our program code execution will be taken care by the Main thread. If we create any new threads to execute some of the methods those will become a child threads for the Main thread and our application will become a multithreaded application.

 

Foreground threads are the threads which will run until it finishes its work even if, the Main thread completes its process. So, the lifespan of foreground threads will not depend on the Main thread.

 

Following is the example of foreground threads in c#.

 

using System;

using System.Threading;

 

namespace TutlaneExamples

{

    class Program

    {

        static void Main(string[] args)

        {

            Thread t1 = new Thread(new ThreadStart(PrintInfo));

            t1.Start();

            Console.WriteLine("Main Thread Execution Completed");           

        }

        static void PrintInfo()

        {

            for (int i = 1; i <= 3; i++)

            {

                Thread.Sleep(2000);

                Console.WriteLine("i value: {0}", i);

            }

            Console.WriteLine("Child Thread Execution Completed");

        }

    }

}

If you observe the above example, we created a new child thread (t1) and executing the PrintInfo method. In PrintInfo method every time we are pausing the thread execution for 2 seconds using Sleep method.

 

When we execute the above program, we will get the result like as shown below.

 

Main Thread Execution Completed

i value: 1

i value: 2

i value: 3

Child Thread Execution Completed

If you observe the above result, even after completion of Main thread execution, the child thread continued its execution and completed its work.

C# Background Threads

In c#, background threads are just opposite of foreground threads. The background threads will quit its process immediately when Main thread quits. Here, the lifespan of background threads will depend on the Main thread.

 

To make the thread as a background thread, we need to set IsBackground property to true for that thread. Background threads are useful for any operation that should continue as long as an application is running but these will not prevent the application from terminating.

 

Following is the example of creating a background thread by setting IsBackground property to true in c#.

 

using System;

using System.Threading;

 

namespace TutlaneExamples

{

    class Program

    {

        static void Main(string[] args)

        {

            Thread t1 = new Thread(new ThreadStart(PrintInfo));

            t1.Start();

            t1.IsBackground = true;

            Console.WriteLine("Main Thread Execution Completed");

        }

        static void PrintInfo()

        {

            for (int i = 1; i <= 3; i++)

            {

                Console.WriteLine("i value: {0}", i);

                Thread.Sleep(2000);

            }

            Console.WriteLine("Child Thread Execution Completed");

        }

    }

}

If you observe the above example, we created a new child thread (t1) and set IsBackground property to true to make the child thread (t1) as background thread.

 

When we execute the above program, we will get the result like as shown below.

 

i value: 1

Main Thread Execution Completed

 If you observe the above result, the child thread process quits immediately after completion of Main thread execution.

C# Thread Overview

Following are the important points which we need to remember about threads in c#.

 

  • In c#, the thread is a basic unit of execution within the process and it is responsible for executing the application logic.
  • By default, every program will carry one thread to execute the program logic and that thread is called the Main thread.
  • In c#, to work with threads we need to import System.Threading namespace in our program. 
  • After importing System.Threading namespace in our program, we can create or access the threads using Thread class.
  • In c#, the Main thread will automatically create to handle the program logic. If we create any other threads in our program by using Thread class those will become a child threads for the Main thread.
  • In c#, each thread will have a life cycle and it will start when we create an instance of the object using Thread class.
  • In c#, by using Abort() method of Thread class we can end or abort the thread execution process.
  • In c#, two types of threads are available, those are foreground threads and background threads.
  • Foreground threads are the threads which will run until it finishes its work even if, the Main thread completes its process.
  • Background threads will quit its process immediately when Main thread quits.

In the next chapters, we will learn more about using multiple child threads with examples.

 
 
 

Topics Covered