Multithreading in C#

In c#, multithreading means executing multiple threads simultaneously to perform multiple tasks at a time.

 

The perfect example of multithreading is the operating system. For example, in the windows operating system, we can open multiple applications like excel, word, notepad, browser, etc., to perform multiple tasks simultaneously. In an operating system, each application process will be taken care by separate threads.

 

As we discussed in threading in c#, by default, every program will carry one thread to execute the application logic, and that thread is called the Main thread. So, we can say that every program or application is by default a single-threaded model.

 

When we start a program execution, the Main thread will create automatically, and it is responsible for executing the programming logic in a synchronous way that means one after another. The second process has to wait until the first process completes its execution, and it’s a time-consuming process.

 

To solve this problem, multithreading has been introduced to execute multiple tasks simultaneously (asynchronous way) by creating multiple threads in our application. The threads we will create in our application will become child threads for the Main thread.

 

In c#, the child threads are responsible for executing the tasks in an asynchronous way which means executing multiple tasks simultaneously.

 

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

 

To learn more about threads in c#, check Threading in c#.

C# Single Threaded Model Example

Following is the example of creating the application without having any child threads in c#.

 

using System;
using System.Threading;

namespace TutlaneExamples
{
    class Program
    {
       static void Main(string[] args)
       {
          PrintInfo1();
          PrintInfo2();
          Console.ReadLine();
       }
       static void PrintInfo1()
       {
          for (int i = 1; i <= 4; i++)
          {
             Console.WriteLine("i value: {0}", i);
             Thread.Sleep(1000);
          }
          Console.WriteLine("First method completed");
       }
       static void PrintInfo2()
       {
         for (int i = 1; i <= 4; i++)
         {
            Console.WriteLine("i value: {0}", i);
         }
         Console.WriteLine("Second method completed");
       }
    }
}

The above example shows that we created two methods (PrintInfo1, PrintInfo2). Here, in the PrintInfo1 method, we are making the Main thread sleep for 1 second for every iteration, and after 1 second, it will resume its process and continue the next iteration. The second method PrintInfo2 has to wait (4 seconds) until the first method PrintInfo1 completes its execution.

 

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

 

i value: 1
i value: 2
i value: 3
i value: 4
First method completed
i value: 1
i value: 2
i value: 3
i value: 4
Second method completed

If you observe the above result, the second method (PrintInfo2) has waited until the first method (PrintInfo1) completes its execution.

 

The second method (PrintInfo2) has waited around 4 seconds to start its execution. To overcome the drawback of a single-threaded model, we need to implement a multithreading approach to execute the tasks simultaneously.

C# Multithreading Example

Following is the example of creating multiple threads to execute the multiple tasks simultaneously in c#.

 

using System;
using System.Threading;

namespace TutlaneExamples
{
   class Program
   {
      static void Main(string[] args)
      {
         // Create child threads
         Thread t1 = new Thread(new ThreadStart(PrintInfo1));
         Thread t2 = new Thread(new ThreadStart(PrintInfo2));
         t1.Start();
         t2.Start();
         Console.ReadLine();
      }
      static void PrintInfo1()
      {
         for (int i = 1; i <= 4; i++)
         {
            Console.WriteLine("i value: {0}", i);
            Thread.Sleep(1000);
         }
         Console.WriteLine("First method completed");
      }
      static void PrintInfo2()
      {
         for (int i = 1; i <= 4; i++)
         {
            Console.WriteLine("i value: {0}", i);
         }
         Console.WriteLine("Second method completed");
      }
   }
}

The above example shows that we created two threads (t1, t2) using Thread class to execute PrintInfo1 & PrintInfo2 methods simultaneously. When we start the program execution, both threads (t1, t2) will simultaneously perform assigned tasks.

 

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

 

i value: 1
i value: 1
i value: 2
i value: 3
i value: 4
Second method complete
i value: 2
i value: 3
i value: 4
First method completed

If you observe the above result, while the first method (PrintInfo1) is waiting for the next iteration, the second method (PrintInfo2) has completed its execution instead of waiting for the first method (PrintInfo1) execution.

 

This is how we can implement the multithreading in c# to execute the multiple tasks simultaneously based on our requirements.