Multithreading in C#


You might have already come across this multithreading word or multithreading concept in C# .NET, or in any other programming language.
In my case, I came across the word multithreading many times. When I tried to gain an understanding of it through articles and documents, almost all the articles explained multithreading clearly but many authors couldn’t explain how it is different, in fact, some authors specified it as it is completely asynchronous. But I haven't seen an explanation anywhere about how this multithreading, Parallel Programming, and an asynchronous are different at least in their own way of doing things and this creates confusion among readers.
Here, in this article, I’ll try to explain the concept in an easy way. I’ll try focusing on what is multithreading, why we use it and in what type of situations it is most useful. Also, is it different from asynchronous or not, and the structure of multithreading along with some basic examples in order to understand.
Before getting into details, we define, what is a thread and multithreading metaphorically in the real world.
What is Thread?
 A Word Editor saving the article automatically from time to time is known as Thread. (This means that it's one way of execution).
What is Multi Thread?
While Word Editor is saving the article, Grammarly is working behind to find the mistakes in the sentences is known as Multithread. (Having more than one execution.)
What is Multithreading?
Making use of multi-threads in a program where all are running at the same time but performing different tasks.
What is the use of threading?
Thread helps in improving application performance by doing things in a way of parallel programming.
What is Parallel Programming?
It is the flow of program where the application is broken into parts and for each part, there will be CPU's which deals at the same time. So, by dividing these parts the overall time taken by an application will be reduced that’s how an application performance will be increased.
(This means that it's saying Hey! My name is parallel, I simply distribute my work so that there won't be a burden on me, and all my friends who have taken my work will return it to me at the same time after finishing it and I’ll wait until they do so)
Are Parallel Programming and Asynchronous the same?
Asynchronous is a nonblocking way of doing things, it executes without waiting for an event, and carry on with things.
(This means It's saying Hey! I'm asynchronous, please go and do this task for me and come back with results after you have finished, and meanwhile, I’ll do some other work). You can find more about asynchronous here.
The difference is, Parallel mostly depends on Hardware whereas synchronization is about Tasks, and Threading is about workers.
C# supports parallel execution of code with the help of multithreading. (means multithreading is about the parallel way of execution)

Structure of Multithreading

We use the “Thread” Keyword which is a class taken from the System.Threading namespace.
How a Thread is created?
To implement a thread, we need to make use of threading namespace in our program and this namespace has Thread class, we use this to create a Thread object and these threads objects create threads in the application.
How Threading Works?
In multithreading, the thread scheduler takes help from the operating system to schedule threads so that it can allocate time for each thread.
In a single Processor machine, only one thread executes at a time and for dual-core processor ideally, we can have about 4 threads and for a quad-core processor, we can create up to 8 threads. Improper management also creates more threads on a single processor machine that may lead to resource bottleneck.
Example Program on Multithreading
  1. using System;  
  2. using System.Threading;  
  3. class Program {  
  4.     public static void Main() {  
  5.         Thread ThreadObject1 = new Thread(Example1); //Creating the Thread    
  6.         Thread ThreadObject2 = new Thread(Example2);  
  7.         ThreadObject1.Start(); //Starting the Thread    
  8.         ThreadObject2.Start();  
  9.     }  
  10.     static void Example1() {  
  11.         Console.WriteLine("Thread1 Started");  
  12.         for (int i = 0; i <= 5; i++) {  
  13.             Console.WriteLine("Thread1 Executing");  
  14.             Thread.Sleep(5000); //Sleep is used to pause a thread and 5000 is MilliSeconds that means 5 Seconds    
  15.         }  
  16.     }  
  17.     static void Example2() {  
  18.         Console.WriteLine("Thread2 Started");  
  19.         for (int i = 0; i <= 5; i++) {  
  20.             Console.WriteLine("Thread2 Executing");  
  21.             Thread.Sleep(5000);  
  22.         }  
  23.     }  
  24. }  

Example Program to differentiate MainThread with Worker Thread

What is MainThread?
A Thread that executes first in a process is known as the MainThread.
What does Process mean in Multithreading?
To execute a program, we need some resources provided by this Process. Each process starts with a single thread, called a primary thread. This Process also has the ability to create additional threads from the thread it possesses.
What is Synchronization?
Synchronization is a concurrent execution of two or more threads.
Why this synchronization is needed?
Synchronization avoids conflicts between threads, these conflicts arise when they are running in a parallel way trying to modify some variables. Synchronization makes sure that only one process or thread accesses the critical section of the program.
How do we manage Synchronization?
To handle this, we have various methods, divided into 4 categories
  • Blocking Methods
  • Locking Constructs
  • No blocking Synchronization
  • Signaling
Here, we try to demonstrate a few methods for understanding:


In the thread, synchronization join is a blocking mechanism that helps in pausing the calling thread. This continues until the thread execution has finished on which the join is called.
Here we try to find the differences with Join() and without Join():
  1. using System;  
  2. using System.Threading;  
  3. class Program {  
  4.     public static void Main() {  
  5.         //Creating the WorkerThread with the help of Thread class.    
  6.         Thread ThreadObject1 = new Thread(WorkerThread);  
  7.         ThreadObject1.Start(); //Starting the Thread    
  8.         //ThreadObject1.Join(); //Using Join to block the current Thread    
  9.         Console.WriteLine("1. MainThread Started");  
  10.         for (int i = 0; i <= 3; i++) {  
  11.             Console.WriteLine("-> MainThread Executing");  
  12.             Thread.Sleep(3000); //Here 5000 is 5000 Milli Seconds means 5 Seconds    
  13.         }  
  14.         // We are calling the Name of Current running Thread using CurrentThread    
  15.         Thread Th = Thread.CurrentThread;  
  16.         Th.Name = "Main Thread";  
  17.         Console.WriteLine("\nGetting the Name of Currently running Thread");  
  18.         //Name Property is used to get the name of the current Thread    
  19.         Console.WriteLine($ "Current Thread Name is: {Th.Name}");  
  20.         //Priority Property is used to display the Priority of current Thread    
  21.         Console.WriteLine($ "Current Thread Priority is: {Th.Priority}");  
  22.     }  
  23.     static void WorkerThread() {  
  24.         Console.WriteLine("2. WorkerThread Started");  
  25.         for (int i = 0; i <= 3; i++) {  
  26.             Console.WriteLine("-> WorkerThread Executing");  
  27.             Console.WriteLine("Child Thread Paused");  
  28.             //Sleep method is used to pause the Thread for a specific period    
  29.             Thread.Sleep(3000);  
  30.             Console.WriteLine("Child Thread Resumed");  
  31.         }  
  32.     }  
  33. }  
Output - Using Join
Multithreading In C#
Output - Without using Join
Multithreading In C#
In the above program in Main() to understand clearly, the threads that are created using Thread Class are called child Threads, you can see, using this Thread Class we created Worker Thread, so WorkerThread is known to be Child Thread, and the Main() is known to be the Parent.


The lock helps in Locking the current Thread so that no other thread can interrupt the execution. Unlocking happens after the execution finishes.
Example Code for Lock Synchronization Method
  1. using System;  
  2. using System.Threading;  
  3. namespace LockDemo {  
  4.     class LockExample1 {  
  5.         //Creating a normal Method to Display Names    
  6.         public void Display() {  
  7.             //Lock is used to lock-in the Current Thread    
  8.             lock(this) {  
  9.                 for (int i = 0; i <= 3; i++) {  
  10.                     Thread.Sleep(3000);  
  11.                     Console.WriteLine($ "My Name is Abhishek{i}");  
  12.                 }  
  13.             }  
  14.         }  
  15.     }  
  16.     class Example2 {  
  17.         public static void Main(string[] args) {  
  18.             //Creating object for LockExample1 Class as _locker so that we can access its Display Method    
  19.             LockExample1 _locker = new LockExample1();  
  20.             Console.WriteLine("Threading with the help of Lock");  
  21.             //Calling the Display Method using ThreadStart Delegate which is supplied to Thread constructor.    
  22.             Thread t1 = new Thread(new ThreadStart(_locker.Display));  
  23.             Thread t2 = new Thread(new ThreadStart(_locker.Display));  
  24.             t1.Start(); //Starting Thread1    
  25.             t2.Start(); //Starting Thread2    
  26.         }  
  27.     }  
  28. }  
Output - Threading With Lock
Multithreading In C#
Output - Threading Without Lock
Multithreading In C#
In the above program, we used a normal Display method with Lock() to lock the thread. To Display these names we have to use a ThreadStart which is a Delegate that represents a method to be invoked when this thread begins executing.


In Deadlock, the two threads each wait for the resource which is needed but these resources are held by each other making both of them not to proceed further. (This means It's saying Hey! I'm Deadlock, my friends Lock1 and Lock2 are not releasing their resources and they couldn't understand each other. Lock1 has Lock2 resources and Lock2 has Lock1 resources and they created confusion, so I have no option but to stop this situation of Deadlock).
Example Program for Deadlocks
  1. using System;  
  2. using System.Threading;  
  3. namespace DeadlocksDemo {  
  4.     public class Locking {  
  5.         static readonly object Lock1 = new object();  
  6.         static readonly object Lock2 = new object();  
  7.         static void Display() {  
  8.             Console.WriteLine("Trying to lock Locker1");  
  9.             lock(Lock1) {  
  10.                 Console.WriteLine("Locked Locker1");  
  11.                 Thread.Sleep(1000);  
  12.                 Console.WriteLine("Locking Locker2");  
  13.                 lock(Lock2) {  
  14.                     Console.WriteLine("Locked Locker2");  
  15.                 }  
  16.                 Console.WriteLine("Released Locker2");  
  17.             }  
  18.             Console.WriteLine("Released Locker1");  
  19.         }  
  20.         static void Main() {  
  21.             new Thread(new ThreadStart(Display)).Start();  
  22.             Thread.Sleep(1000);  
  23.             Console.WriteLine("Trying to lock Locker2");  
  24.             lock(Lock2) {  
  25.                 Console.WriteLine("Locked Locker2");  
  26.                 Console.WriteLine("Locking Locker1");  
  27.                 lock(Lock1) {  
  28.                     Console.WriteLine("Locked Locker1");  
  29.                 }  
  30.                 Console.WriteLine("Released Locker1");  
  31.             }  
  32.             Console.WriteLine("Released Locker2");  
  33.             Console.Read();  
  34.         }  
  35.     }  
  36. }  
Multithreading In C#
In the above program, the Lock inside both methods is waiting for each other to finish. For both to achieve their goals they need to release, but they are not doing so. As both couldn’t achieve what they are expecting, this type of accessing only makes threads freeze and is ultimately prone to Deadlocks.


I hope that you got an idea of the threading concept in C# by knowing all its real definitions and its relations with other methods. But there is more to learn, because multithreading is a huge concept in C# with various methods and workarounds. To know more about Threading in C#, this page has in-depth information here.
Happy Coding!