RSS Feed
Download our iPhone app
Browse DevX
Sign up for e-mail newsletters from DevX


Working with .NET Threads

This article describes the dos and don'ts of the Thread class, and presents a wrapper class that simplifies starting a thread, correctly terminates a thread, and offers a more consistent class interface than that of the raw Thread class.

he .NET class Thread defined in the System.Threading namespace represents a managed thread. The Thread class offers raw control over the underlying operating system thread. However, with power comes liability, and usually most of the Thread class methods and properties should not be used by application developers. The article explains the rational behind its recommendations, and presents a higher-level wrapper class around the Thread type. The wrapper class provides only the safe methods, as well as compensates for basic deficiencies in the Thread class design.

Managing Thread ID
You can get hold of the current thread your code runs on using the CurrentThread read-only static property of the Thread class:

   public sealed class Thread 
      public static Thread CurrentThread { get; }
      // Other methods and properties

The CurrentThread property returns an instance of the Thread class. Each thread has a unique thread identification number called thread ID. You can access the thread ID via the GetHashCode() method of the Thread class:

   Thread currentThread = Thread.CurrentThread;
   int threadID = currentThread.GetHashCode();
   Trace.WriteLine("Thread ID is "+ threadID);

Thread.GetHashCode() is guaranteed to return a value that is unique process-wide. It is worth mentioning that the thread ID obtained by GetHashCode() is unrelated to the native thread ID allocated by the underlying operating system. You can verify that by opening the Thread's debug window (under Debug|Windows) during a debug session, and examining the value of the ID column (see Figure 1). The ID column reflects the physical thread ID. Having different IDs allows for .NET threads in the future to map differently to the native operating system support. If you need to programmatically access the physical thread ID your code runs on, use the static method GetCurrentThreadId() of the AppDomain class:

   int physicalID = AppDomain.GetCurrentThreadId();
   int hashedID   = 
   Debug.Assert(physicalID != hashedID);

Another useful property of the Thread class is the Name string property. Name allows you to assign a human-readable name to a thread:

   Thread currentThread = Thread.CurrentThread;
   string threadName = "Main UI Thread";
   currentThread.Name = threadName;

The thread name can only be assigned by the developer, and by default, a new .NET thread is nameless. Although naming a thread is optional, I highly recommend doing so, because it is an important productivity feature. Windows does not have the ability to assign a name to a thread. In the past, when developers debugged native Windows code, they had to record the new thread ID in every debugging session (using the Threads debug window). These IDs were not only confusing (especially when multiple threads were involved) but also changed in each new debugging session. The Thread's Debug window of Visual Studio .NET (see Figure 1) displays the value of the Name property, thus easing the task of tracing and debugging multithreaded applications. In addition, when a named thread terminates, VS .NET will automatically trace to the Output window the name of that thread, as part of the thread's Exit method.

Thanks for your registration, follow us on our social networks to keep up-to-date