Thread in C#

In order to under Thread in C#, we need to understand how the operating system works.

A Thread of execution is the smallest sequence of programmed instructions that can be managed independently by a Scheduler. Threads and Processes are different in Operating Systems, a thread is a component of a process; multiple Threads can exist within one Process.

Multiple Threads can exist within one process, executing concurrently and sharing resources; while different Processes do not share these resources.

Resource from Wikipedia

In my opinion, Thread is limited isolated and Process is completely isolated.

In a modern computer or mobile device, one process can have more than one thread, which means it can perform more than one task at a time; whereas, the traditional process (Single-Thread Process) can only have one thread.

Multiple Tread in One Process

As we can see above, one process has two threads and the two threads share the code, data and files.


There are two kinds of threads in .NET Core applications, Foreground Thread and Background Thread.

Foreground Thread

  • These threads keep running even after the application exits or quits
  • These threads prevent the current application from terminating
  • CLR does not shut down the application until all Foreground Threads have stopped

Background Thread

  • These threads quit, if the application’s main thread (Foreground Thread) quits

By default, every thread developers create is a Foreground Thread.

In .NET Core, the CLR plays a major role in creating and managing threads life cycle.


In some articles, I have been noticing Threads are categories into Main Thread and Worker Thread. These concepts are widely used when we develop UI based application, regardless of desktop or mobile applications.

In my opinion, the definition of the Main Thread or Worker Thread is not cast in stone. It can vary depends on the situation. However, managing UI in a primary thread and managing long execution tasks in the worker thread is a commonly used solution. You can’t say it is right or wrong, whereas it can be expensive to other developers if we don’t follow the “protocol”. A good programmer should write readable code.

Windows application generally uses a single primary thread to manage the UI; the thread is responsible for creating, drawing and managing the UI. And the thread that is responsible for executing operation/methods in the background mode is often called a Worker Thread. Compared with the worker thread, the primary thread is always referred to as the Main Thread.

In a multithreading programming approach, the Worker Thread should never try to manage the UI (visual control). Because the application UI may be blocked or frozen, which could shrink the user experience.


Code Example – Establish A Thread

The following code snippet demonstrates how to establish a thread and run a method on that thread. Image the Main Thread is handling the UI components and the Worker Thread is handling a long process; for example, we need to download an XML file from a remote server in the background. The UI components may get block if we don’t put the long process into a Worker Thread.

In my opinion, the thread is main thread by default, any thread made manually is worker threads.

class Program
     {
         static void Main(string[] args)
         {
             Thread thread = new Thread(WriteUsingNewThread);
             //Worker Thread
             thread.Start();
             //Main Thread
             for (int i = 0; i < 10000; i++)
             {
                 Console.Write(" A" + i + " ");
             }
         }
         private static void WriteUsingNewThread()     
         {         
             for (int i = 0; i < 10000; i++)         
             {             
                 Console.Write(" Z" + i + " ");         
             }     
         } 
     }

Share Resource

In regard to the implementation of multi-threading, it is managed internally by a thread scheduler. In .NET, CLR delegates thread scheduling task to the operating system.

The CLR assigns each thread its own local memory stack to keep local variable separate, and the separate copy of local variables is created on each thread’s memory stack. Have a look the diagram blow.

As we can see, there are two threads in the diagram. Thread 1 and Thread 2 are calling the same For-Loop. The program needs to access the value of i constantly to run through the loop. As we are expecting, the value of i in Thread 1 and Thread 2 are not relevant at all. In another word, Thread 1 and Thread 2 don’t interfere with each other at all. The access and use of data or method happen simultaneously.

However, sometimes we don’t want to a method be accessed by other threads while one thread is using it. In this case, we need to use a lock to ensure the implementation.

In my opinion, locking can make sure that we don’t end up getting problems because of resource sharing.

Have a look the following code

class Program
{
    private static bool isCompleted;
    static readonly object lockCompleted = new object();
    static void Main(string[] args)     
    {         
        //Worker Thread         
        Thread thread = new Thread(HelloWorld);         
        thread.Start();         
        //Main Thread         
        HelloWorld();         
        Console.ReadLine();     
    }     
    private static void HelloWorld()     
    {         
        lock (lockCompleted)         
        {             
            if (!isCompleted)             
            {                 
                isCompleted = true;                 
                Console.WriteLine("Hellow World should print only once");             
            }         
         }     
    } 
}

We introduce the lock on line 4, by declaring an object named lockCompleted. We put the lock on line 16. What happens there is when a thread is running the HelloWorld method, other thread will have to wait or queen till the current thread is finished.

In this particular case, the HelloWorld method will only be called once.


Thread Pool

Every thread has overhead in time and memory and every thread consumes one megabyte of memory. Thread pools reduce the performance penalty by sharing and recycling threads.

Very Importantly, Thread pool only create background threads.

To create a background thread, we create a new thread and set the background property as TRUE. In production, the number of threads that can run simultaneously sometimes need to be limited. Once the limit is reached, all jobs form a queen and begin only when another job finishes.

In my opinion, we should limit the Thread Pool number in production. Because our development machine may be different from the deployment machines. By limiting the Thread Pool number could assisting in our program stability.

Code Example – Thread Pool

class Program
{
    static void Main(string[] args)
    {
      Employee employee = new Employee();          
      employee.Name = "Tanaka";         
      employee.CompanyName = "ddd";         
      ThreadPool.QueueUserWorkItem(new WaitCallback(DisplayEmployeeInfo), employee);          
      Console.WriteLine(Thread.CurrentThread.IsThreadPoolThread);         
      Console.ReadKey();     
     }     
     private static void DisplayEmployeeInfo(object employee)     
     {         
          
     Console.WriteLine("DisplayEmployeeInfo" + " " +Thread.CurrentThread.IsThreadPoolThread);         
     Employee emp = employee as Employee;         
     Console.WriteLine("Person name is {0} and company name is {1}", emp.Name, emp.CompanyName);     
     } 
} 
     public class Employee 
     {     
        public string Name { get; set; }
        public string CompanyName { get; set; } 
     }

As we can see from the above code snippet, I register the DisplayEmployeeInfo method in the Thread Pool on line 8.

The console will print the following output, and we can see the DisplayEmployeeInfo method is on the Thread Pool

Console Output

Error Handling per Thread

Another thing we need to pay attention to is, Error handling in Thread is per Thread. In other words, the error on Worker Thread won’t be handled in the Main Thread.

class Program
{
    static void Main(string[] args)
    {
        Demo();
    }
    private static void Demo()     
    {         
        try   
        {             
            //Worker Thread            
            new Thread(Execute).Start();         
        }                  
        catch (Exception ex)         
        {             
            //Main Thread
            Console.WriteLine(ex.Message);         
        }     
    }     
    static void Execute()     
    {         
       throw null;     
    } 
}

In this particular case, Visual Studio will throw an error on 23, instead of the try-catch exception. Because the Execute method was called on a Worker Thread and the catch block is on the Main Thread.


4 Replies to “Thread in C#”

  1. “I was pretty pleased to discover this great site. I wanted to thank you for your time for this particularly wonderful read!! I definitely really liked every bit of it and I have you saved to fav to see new things in your website.”
    נערות ליווי בקיסריה

  2. “The next time I read a blog, Hopefully it does not disappoint me as much as this particular one. I mean, Yes, it was my choice to read through, nonetheless I really believed you would have something interesting to say. All I hear is a bunch of complaining about something you could possibly fix if you were not too busy seeking attention.”
    נערות ליווי בקיסריה

Leave a Reply

Your email address will not be published. Required fields are marked *