joydip_kanjilal
Contributor

How to work with threads in C#

how-to
Aug 13, 20184 mins
C#Small and Medium BusinessSoftware Development

Take advantage of multithreading to perform several tasks simultaneously and improve the responsiveness of your application

thread weave spools connected rotate spin
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.

joydip_kanjilal
Contributor

Joydip Kanjilal is a Microsoft Most Valuable Professional (MVP) in ASP.NET, as well as a speaker and the author of several books and articles. He received the prestigious MVP award for 2007, 2008, 2009, 2010, 2011, and 2012.

He has more than 20 years of experience in IT, with more than 16 years in Microsoft .Net and related technologies. He has been selected as MSDN Featured Developer of the Fortnight (MSDN) and as Community Credit Winner several times.

He is the author of eight books and more than 500 articles. Many of his articles have been featured at Microsoft’s Official Site on ASP.Net.

He was a speaker at the Spark IT 2010 event and at the Dr. Dobb’s Conference 2014 in Bangalore. He has also worked as a judge for the Jolt Awards at Dr. Dobb's Journal. He is a regular speaker at the SSWUG Virtual Conference, which is held twice each year.

More from this author