Master C#

How to work with threads in C#

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

How to work with threads in C#
Thinkstock

Master C#

Show More

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.

Thread t = new Thread(new ThreadStart(MyThreadMethod));

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.

static void Main()
        {
            Thread t = new Thread(new ThreadStart(MyThreadMethod));
            t.Start();           
            Console.Read();
        }
        static void MyThreadMethod()
        {
            Console.WriteLine(“Hello World!”);
        }

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.

Thread t = new Thread(new ThreadStart(MyThreadMethod));
t.Start();
Console.WriteLine(“The thread’s state is: “ + t.ThreadState.ToString());

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.

static void Main()
        {
            Thread t = new Thread(new ThreadStart(MyThreadMethod));
            t.Start();
            t.IsBackground = true;
            Console.WriteLine(“The thread’s background status is: “+t.IsBackground.ToString());
            Console.Read();
        }

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.

Thread t = new Thread(new ThreadStart(MyThreadMethod));
t.Start();
t.Suspend(); //Suspends the newly created thread
t.Resume(); //Resumes the suspended thread

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.

static void Main()
        {
            Thread thread1 = new Thread(new ThreadStart(Method1));
            Thread thread2 = new Thread(new ThreadStart(Method2));
            thread1.Priority = ThreadPriority.Highest;
            thread2.Priority = ThreadPriority.Lowest;
            thread2.Start();
            thread1.Start();
            Console.Read();
        }
        static void Method1()
        {
            for (int i = 0; i < 10; i++)
            {
                Console.WriteLine(“First thread: “ + i);
            }
        }
        static void Method2()
        {
            for (int i = 0; i < 10; i++)
            {
                Console.WriteLine(“Second thread: “ + i);
            }
        }

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.

Copyright © 2018 IDG Communications, Inc.