Take advantage of multithreading to perform several tasks simultaneously and improve the responsiveness of your application Credit: Thinkstock A thread is the smallest unit of execution within a process. Multithreading is the ability to have multiple threads in memory at a given time and switch among them to handle multiple operations at the same time. Microsoft’s .Net Framework provides excellent support for working with threads. Programming threads in C# To work with threads, you should include the System.Threading namespace in your application. To create a new thread, you should leverage the ThreadStart delegate and pass the reference to a method that should execute on the thread. Note that a delegate is a type-safe function pointer. The following code snippet shows how you can create a new thread object using this delegate. <span class="s1">Thread t = new Thread(new ThreadStart(MyThreadMethod));</span> To start the newly created thread, you should call the Start method on the thread object you have created. The following code listing illustrates this. Note that the thread method MyThreadMethod executes on the new thread (called a worker thread) that has been created. <span class="s1">static void Main() </span><span class="s1"> { </span><span class="s1"> Thread t = new Thread(new ThreadStart(MyThreadMethod)); </span><span class="s1"> t.Start(); </span><span class="s1"> Console.Read(); </span><span class="s1"> } </span><span class="s1"> static void MyThreadMethod() </span><span class="s1"> { </span><span class="s1"> Console.WriteLine(“Hello World!”); </span><span class="s1"> }</span> Display thread states in C# A thread in memory can be in different states—Aborted, Background, Running, Stopped, Suspended, Unstarted, etc. Thread states are defined in the ThreadState enumeration available in the System.Threading namespace. Unless the Start method is called on a thread, the thread is in the Unstarted state. When the Start method is invoked on the thread instance, the thread’s state changes from Unstarted to Running. The following code snippet shows how you can display the state of a thread in the console. <span class="s1">Thread t = new Thread(new ThreadStart(MyThreadMethod)); </span><span class="s1">t.Start(); </span><span class="s1">Console.WriteLine(“The thread’s state is: “ + t.ThreadState.ToString());</span> Control foreground and background threads in C# Threads can run either in the foreground or in the background. The threads that you create explicitly are foreground threads. One of the major differences between a foreground thread and a background thread is that your application lives only as long as one or more foreground threads are running. In essence, foreground threads prevent the application from being terminated. By contrast, background threads don’t keep the Common Language Runtime environment alive. You can set the background status of a thread using the IsBackground property. Here is a code example that shows how this can be achieved. <span class="s1">static void Main() </span><span class="s1"> { </span><span class="s1"> Thread t = new Thread(new ThreadStart(MyThreadMethod)); </span><span class="s1"> t.Start(); </span><span class="s1"> t.IsBackground = true; </span><span class="s1"> Console.WriteLine(“The thread’s background status is: “+t.IsBackground.ToString()); </span><span class="s1"> Console.Read(); </span><span class="s1"> }</span> You can suspend or resume a thread by invoking the Suspend() and Resume() methods on the thread object. Note that you can only resume a thread that you previously suspended by making a call to the Suspend() method. <span class="s1">Thread t = new Thread(new ThreadStart(MyThreadMethod)); </span><span class="s1">t.Start(); </span><span class="s1">t.Suspend(); //Suspends the newly created thread </span><span class="s1">t.Resume(); //Resumes the suspended thread</span> However, it should be noted that the Thread.Suspend() and Thread.Resume() methods have been deprecated. Rather you should use the AutoResetEvent and EventWaitHandle methods to synchronize activities involving threads. Set thread priority in C# You can control a thread’s priority to determine the relative share of processor time that a thread will get compared to the other threads residing in the memory. Thread priority is defined in the ThreadPriority enumeration. The possible values include: Lowest, BelowNormal, Normal, AboveNormal, and Highest. The following code snippet illustrates how you can set the thread priorities of two threads using the Priority property of the thread object. <span class="s1">static void Main() </span><span class="s1"> { </span><span class="s1"> Thread thread1 = new Thread(new ThreadStart(Method1)); </span><span class="s1"> Thread thread2 = new Thread(new ThreadStart(Method2)); </span><span class="s1"> thread1.Priority = ThreadPriority.Highest; </span><span class="s1"> thread2.Priority = ThreadPriority.Lowest; </span><span class="s1"> thread2.Start(); </span><span class="s1"> thread1.Start(); </span><span class="s1"> Console.Read(); </span><span class="s1"> } </span><span class="s1"> static void Method1() </span><span class="s1"> { </span><span class="s1"> for (int i = 0; i < 10; i++) </span><span class="s1"> { </span><span class="s1"> Console.WriteLine(“First thread: “ + i); </span><span class="s1"> } </span><span class="s1"> } </span><span class="s1"> static void Method2() </span><span class="s1"> { </span><span class="s1"> for (int i = 0; i < 10; i++) </span><span class="s1"> { </span><span class="s1"> Console.WriteLine(“Second thread: “ + i); </span><span class="s1"> } </span><span class="s1"> }</span> When you execute the above code snippet, you will see that the first thread completes its execution ahead of the second thread even though the second thread was started before the first thread in the Main method. Threads are expensive. They consume a lot of resources in your system for initialization, switching contexts, and releasing the resources they consume. Consequently multithreading should be used judiciously and only when it is needed. When you do take advantage of multithreading, it is always advisable to leverage thread pools to create and manage threads on demand and improve the responsiveness of your application. Related content how-to How to use FastEndpoints in ASP.NET Core Take advantage of the free open-source FastEndpoints library to build fast and lean APIs in your ASP.NET Core applications. By Joydip Kanjilal Jul 11, 2024 7 mins Microsoft .NET C# Development Libraries and Frameworks how-to How to use Refit to consume APIs in ASP.NET Core Take advantage of Refit REST library to simplify API consumption and make your code cleaner, more efficient, and easier to maintain. By Joydip Kanjilal Jul 04, 2024 10 mins C# Microsoft .NET Software Deployment how-to When to use an abstract class vs. interface in C# Understanding the differences between an abstract class and interface is key to designing loosely coupled and extensible applications. By Joydip Kanjilal Jun 20, 2024 10 mins Small and Medium Business Microsoft .NET C# how-to 6 security best practices for ASP.NET Core Learn the best practices and built-in safeguards for preventing attacks and protecting sensitive data in your ASP.NET Core web applications. By Joydip Kanjilal Jun 07, 2024 6 mins C# Microsoft .NET Web Development Resources Videos