Multithreading in C#

Multithreading in C# with Examples

In this article, I am going to discuss Multithreading in C# with examples. Multithreading is one of the most important concepts in C# that you need to understand as a developer. In this and a few upcoming articles, I am going to cover all the concepts of C# Multithreading with examples. As part of this article, I am going to cover the following pointers.

  1. What is Multitasking?
  2. How Does the Operating System Execute Multiple Applications at a time?
  3. What is a Process?
  4. What is a Thread?
  5. Example to Understand Threading in C#.
  6. Understanding the Thread Class in .NET Framework.
  7. What are the Drawbacks of Single-Threaded Applications?
  8. How to Overcome the Drawbacks of Single-Threaded Application using Multithreading?
  9. What is Multithreading in C#?
  10. What is Thread Class in C#?
What is Multitasking?

Before understanding the concept of Multithreading in C#, let us first understand multitasking. As the name says, multitasking means performing multiple tasks at the same time. Windows Operating System is a multitasking operating system. It means it has the ability to run multiple applications at the same time. For example, on my machine, I can open the Google Chrome Browser, Microsoft word document, Notepad, VLC Media Player, Visual Studio, etc. at the same time. This is possible because on my machine I have installed the Windows operating system and the Windows operating system is a multitasking operating system.

How Does the Operating System Execute Multiple Applications at a time?

To execute multiple applications (Google Chrome Browser, Microsoft word document, Notepad, VLC Media Player, Visual Studio, etc) at the same time, the operating system internally makes use of processes.

What is a Process?

A process is a part of the operating system (or a component under the operating system) which is responsible for executing the program or application. So, to execute each and every program or application, there will be a process.

You can see the process which are executing the programs or applications using the Task Manager. Just right-click on the Taskbar and click on the Task Manager option which will open the Task Manager window. From that window, just click on the “Processes” button as shown below.

Multithreading in C#

As you can see in the above image, each application is executed by one corresponding process. Along the same line, there are also multiple processes that are running in the background which are known as the background processes. These background processes are known as windows services and the Operating system runs a lot of windows services in the background.

So, we have an operating system and under the operating system, we have processes that run our applications. So, the point that you need to remember is under the process, an application runs. To run the code of an application the process internally makes use of a concept called Thread.

What is Thread?

Generally, a Thread is a lightweight process. In simple words, we can say that a Thread is a unit of a process that is responsible for executing the application code. So, every program or application has some logic or code, and to execute that logic or code, Thread comes into the picture.

By default, every process has at least one thread that is responsible for executing the application code and that thread is called Main Thread. So, every application by default is a single-threaded application.

Note: All the threading-related classes in C# belong to System.Threading namespace. 

Example to Understand Threading in C#:

Let us see an example to understand Threading in C#. The following is a simple program where we are having a class called Program and, in that class, we are having a method called Main which is simply printing a message on the Console window.

using System;
namespace ThreadingDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Welcome to Dotnet world!");
            Console.ReadKey();
        }
    }
}
Does the above Program when run makes use of Thread?

Yes, there is a Thread and that thread is going to execute our application code and that thread is called Main Thread. Now let us prove this. Now, put a debugger point on your application code and then run the application. Let us assume you put the debugger point on line number 9 and when you run the application, you will see that the debugger will hit that point as shown in the below image.

Does the above Program when run makes use of Thread?

Once the debugger hit the debugging point, select the Debug => Windows => Threads options from the Visual Studio menu as shown in the below image.

Example to Understand Threading in C#

Once you select the Debug => Windows => Threads options, then it will open the following window. You can see here that the Main Thread is currently executing the Main method of the Program class.

single-threaded application in C#

So, this proves that by default every application is a single-threaded application and by default, the Main thread is going to execute our application code.

Thread Class in C#:

If you go to the definition of Thread Class in C#, then you will see that it contains one static property called CurrentThread which is going to return the instance of the currently executing thread i.e. the thread which is running your application code. If you go to the definition of Thread class then you will find the following signature.

Thread Class definition in C#

As you can see the CurrentThread static property return type is Thread i.e. it is going to return the instance of the currently executing thread. Along the same line, there is a non-static property called Name using which we can set and get the Name of the currently executing thread.

Note: By default, the thread does not have any name. If you want then you can provide any name to the thread by using the Name property of the Thread class. So, modify the program as shown below where we are setting the Name property of the thread class as well as printing the Name property.

using System.Threading;
using System;
namespace ThreadingDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            Thread t = Thread.CurrentThread;
            //By Default, the Thread does not have any name
            //if you want then you can provide the name explicitly
            t.Name = "Main Thread"; 
            Console.WriteLine("Current Executing Thread Name :" + t.Name);
            Console.WriteLine("Current Executing Thread Name :" + Thread.CurrentThread.Name);

            Console.Read();
        }
    }
}
Output:

What are the drawbacks of Single-Threaded Applications?

As you can see, in order to run the application code, one thread is created i.e. the Main Thread. So, this proves that, by default, every application is a single-threaded application.

What are the drawbacks of Single-Threaded Applications in .NET Framework?

In a single-threaded application, all the logic or code present in the program will be executed by a single thread only i.e. the Main thread. For example, if we have three methods in our application and if all these three methods are going to be called from the Main method. Then the Main thread is only responsible to execute all these three methods sequentially i.e. one by one. It will execute the first method and once it completes the execution of the first method then only it executes the second method and so on. Let us understand this with an example. Modify the program as shown below.

using System;
namespace ThreadingDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            Method1();
            Method2();
            Method3();
            Console.Read();
        }

        static void Method1()
        {
            for (int i = 1; i <= 5; i++)
            {
                Console.WriteLine("Method1 :" + i);
            }
        }
        
        static void Method2()
        {
            for (int i = 1; i <= 5; i++)
            {
                Console.WriteLine("Method2 :" + i);
            }
        }

        static void Method3()
        {
            for (int i = 1; i <= 5; i++)
            {
                Console.WriteLine("Method3 :" + i);
            }
        }
    }
}
Output:

Single Thread Application in C#

As you can see in the above output, the methods are called and executed one after the other. The Main thread first executes Method1 and once it completes the execution of Method1 then it calls Method2 and then Method3.

What is the problem with the above Program Execution?

In our example, we are just writing some simple code to print the values from 1 to 5 within the method body. What will you do if one method is taking more than the expected time? Suppose Method2 is going to interact with a database or it is going to invoke any web services or any web APIs which will take more than 10 seconds to provide the response. In that case, the Method2 execution will be delayed for 10 seconds as it is waiting there to get a response back either from the database, from the Web Service, or from the Web API. Until Method2 is not completed its execution, Method3 is not going to be executed because of the sequential execution of the program i.e. one by one.

Example to Understand the Problem of Single-Threaded Application in C#.

Here we are not going to perform any database or Web Service call instead we are going to use the Thread class Sleep method to delay the execution of Method2 for 10 seconds. Following is the signature of the Sleep Method. Another overloaded version of the Sleep method is available which takes TimeSpan as input and that we will discuss in our coming articles.

public static void Sleep(int millisecondsTimeout);

The sleep method takes the time in milliseconds as input and then suspends the current thread execution for that specified number of milliseconds. So, please modify the Program class code as shown below.

using System.Threading;
using System;
namespace ThreadingDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            Method1();
            Method2();
            Method3();
            Console.Read();
        }
        static void Method1()
        {
            for (int i = 1; i <= 5; i++)
            {
                Console.WriteLine("Method1 :" + i);
            }
        }

        static void Method2()
        {
            for (int i = 1; i <= 5; i++)
            {
                Console.WriteLine("Method2 :" + i);
                if (i == 3)
                {
                    Console.WriteLine("Performing the Database Operation Started");
                    //Sleep for 10 seconds
                    Thread.Sleep(10000);
                    Console.WriteLine("Performing the Database Operation Completed");
                }
            }
        }
        static void Method3()
        {
            for (int i = 1; i <= 5; i++)
            {
                Console.WriteLine("Method3 :" + i);
            }
        }
    }
}

Now run the application and notice that the Method2 execution is delayed for 10 seconds. Once Method2 completes its execution then only Method3 starts its execution. This is because all these three methods are executed by a single thread and this is the drawback of the single-threaded application.

How to solve the above problem?

To solve the above problem, we are provided with a concept called Multithreading in C#. As we already discussed Operating System has Processes which is used to run our applications. The Process contains Thread which will actually run our application code.

A process by default makes use of a single thread to run our application code but a process can have multiple threads, and multiple threads can run our application code simultaneously. In this case, each thread is going to perform a different task or you can say each thread is going to execute different parts of our application code.

In our application, we have three methods. So, the three methods that we defined in our application can be executed by three different threads. The advantage is that the execution takes place simultaneously. So, when multiple threads try to execute the application code, then the operating system allocates some time period for each thread to execute.

Now, in our example, we want to execute the three methods using three different threads. let us say t1, t2, and t3. The thread t1 is going to execute Method1, thread t2 is going to execute the Method2. At the same time, Method3 is going to be executed by thread t3. Let us modify the Program class as shown below to execute the three methods with three different Threads. Here, the main method is going to be executed by the Main thread and the Main thread is going to create the child threads.

using System.Threading;
using System;
namespace ThreadingDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Main Thread Started");

            //Creating Threads
            Thread t1 = new Thread(Method1)
            {
                Name = "Thread1"
            };
            Thread t2 = new Thread(Method2)
            {
                Name = "Thread2"
            };
            Thread t3 = new Thread(Method3)
            {
                Name = "Thread3"
            };

            //Executing the methods
            t1.Start();
            t2.Start();
            t3.Start();
            Console.WriteLine("Main Thread Ended");
            Console.Read();
        }
        static void Method1()
        {
            Console.WriteLine("Method1 Started using " + Thread.CurrentThread.Name);
            for (int i = 1; i <= 5; i++)
            {
                Console.WriteLine("Method1 :" + i);
            }
            Console.WriteLine("Method1 Ended using " + Thread.CurrentThread.Name);
        }

        static void Method2()
        {
            Console.WriteLine("Method2 Started using " + Thread.CurrentThread.Name);
            for (int i = 1; i <= 5; i++)
            {
                Console.WriteLine("Method2 :" + i);
                if (i == 3)
                {
                    Console.WriteLine("Performing the Database Operation Started");
                    //Sleep for 10 seconds
                    Thread.Sleep(10000);
                    Console.WriteLine("Performing the Database Operation Completed");
                }
            }
            Console.WriteLine("Method2 Ended using " + Thread.CurrentThread.Name);
        }
        static void Method3()
        {
            Console.WriteLine("Method3 Started using " + Thread.CurrentThread.Name);
            for (int i = 1; i <= 5; i++)
            {
                Console.WriteLine("Method3 :" + i);
            }
            Console.WriteLine("Method3 Ended using " + Thread.CurrentThread.Name);
        }
    }
}

As you can see in the above code, we have created three different instances of the Thread class. To the constructor of the Thread class, we need to pass the method name which needs to be executed by that Thread. Then we call the Start() method on the Thread class which will start executing the method. You will not get the output in a sequential manner. Run the application and see the output as shown below. The output may vary in your machine.

Multithreading in C# with Examples

Here the Main thread is going to create all other Threads. Here, the main method is going to be executed by the Main thread and the Main thread is going to create the child threads which are called Worker Threads. Now, to see all the threads, run the application in debug mode by putting debugging point and then open Debug => Windows => Threads options, then it will open the following window. You can see here that the Main Thread as well as the Worker threads executing our application code.

What is Multithreading in C#

What is Multithreading in C#?

If multiple threads are used to execute your application code, then it is called Multithreading. Multithreading is a mechanism to implement Concurrent Programming where multiple threads operate simultaneously. Threads are lightweight processes that signify the execution path in a program. Thread usage increases the efficiency of an application and reduces CPU cycle time wastage. The main advantage of using Multithreading is the maximum utilization of CPU resources.

What is Thread Class in C#?
  1. In C#, the Thread class is used to create threads.
  2. With the help of the Thread class, we can create foreground and background threads. What are the foreground and background threads that we are going to discuss in our coming article?
  3. Thread class also allows us to set the priority of a thread. In our coming articles, we will discuss how to set the priority of a thread.
  4. The Thread class in C# also provides the current state of a thread. We will discuss this when we will discuss Thread Life Cycle in C#.
  5. The Thread class in C# is a sealed class, so it cannot be inherited.

In the next article, I am going to discuss Constructors of Thread Class in C# with Examples. Here, in this article, I try to explain the concept of Multithreading in C# with Examples. I hope you understood the basics for C# Multithreading with Examples and enjoy this article.

1 thought on “Multithreading in C#”

Leave a Reply

Your email address will not be published.