Developer

Assemble your .NET application with threads

The System.Threading namespace includes everything necessary to incorporate threading into your .NET application. Take a closer look at threading and its complex nature.

Threading support is one of the many features of the .NET Framework. Previous tools such as Visual Basic included very limited threading support, so C++ was often the only option. Fortunately, the .NET Framework doesn't have this disadvantage. The System.Threading namespace includes everything necessary to incorporate threading into your .NET application. While this is great news (for most), novices are often apprehensive about threading. The terms can be confusing, but everything makes sense when you lay it out.

What is a thread?

A thread is an entity owned by a process that is scheduled for processing time. In a basic application (like the following one), it runs in a single thread:

using System;
public class HelloWorld  {
public const System.String message = "World";
public static void  Main(System.String[] args)  {
System.Console.Out.WriteLine("Hello: " + message);
} }

You may utilize the System.Threading namespace to create your own threads within the application. The System.Threading.Thread object within this namespace represents a single thread of execution. You can start a thread, seeking to accomplish a task in that thread while the current thread continues.

The following listing expands the first example by utilizing the Thread object to create two threads that perform two simple tasks:

using System;
using System.Threading;
public class HelloWorld  {
public const System.String message = "World";
public static void  Main(System.String[] args)  {

Thread t1 = new Thread(new ThreadStart(Test1));
Thread t2 = new Thread(new ThreadStart(Test2));
t1.Start();
t2.Start();
}
static void Test1() {
System.Console.Out.WriteLine("1. Hello: " + message);
}
static void Test2()   {

System.Console.Out.WriteLine("2. Hello: " + message);
}  }

In this example, each method call is performed in its own thread (or process). The ThreadStart delegate passed to the Thread object is contained within the System.Threading namespace as well. It tells the system to start the thread using the specific object (the method name).

Additionally, threads may sleep for a specific amount of time, as well as stop or merge with another thread. You may manage these and other properties via the following methods and/or properties of the Thread class:

  • Abort: Stops the current thread's execution
  • Interrupt: Interrupts a thread in the wait, sleep, or join state
  • Join: Blocks a thread until a specific time interval elapses or it terminates
  • Name: Assigns or retrieves a thread's name
  • Priority: Sets the priority of the thread, allowing one thread to take precedence over others
  • Resume: Resumes thread execution
  • Suspend: Pauses the thread's execution
  • ThreadStatus: Gets the thread's status

The Thread class also contains various static methods (those called with instantiating a Thread object), with the Sleep method being the most discussed. It allows a thread to be suspended for a specific amount of time (milliseconds). The next listing uses it to halt our threads for the specified time:

using System;
using System.Threading;
public class HelloWorld  {
public const System.String message = "World";
public static void  Main(System.String[] args)  {
Thread t1 = new Thread(new ThreadStart(Test1));
Thread t2 = new Thread(new ThreadStart(Test2));
t1.Start();
t2.Start();
}
static void Test1() {
Thread.Sleep(5000);
System.Console.Out.WriteLine("1. Hello: " + message);
}
static void Test2()  {
Thread.Sleep(1500);
System.Console.Out.WriteLine("2. Hello: " + message);
}  }

This changes the order of output based on the amount of time each thread waits. Microsoft defines three approaches to threading in a Win32 environment:

  1. Single: This is the default architecture used if the developer doesn't specify otherwise—one thread corresponding to an application's process. A process may be defined as an application instance that owns that application's memory space. Most Windows applications are single-threaded with one thread doing all of the work.
  2. Apartment: Apartment-threaded code executes within its own thread, confined to its own apartment. A thread can be defined as an entity owned by a process that is scheduled for processing time. In the apartment-threading model, all threads operate within the confines of their own subsections of the main application's memory. This model allows multiple instances of your code to execute simultaneously but independently. You may remember this model from Visual Basic. The ApartmentState property of the Thread class may be used to work with this model.
  3. Free: In the free-threading model, multiple threads can call into the same methods and components at the same time. Unlike apartment threading, they aren't confined to separate memory spaces. This is the most complex model, since it's imperative to track the threads and avoid conflicts.

The details of each threading model are beyond the scope of this article, but it's good to know the choices available when developing an application.

Make a choice

Implementing an elaborate threading scheme isn't imperative to good application design; you should use it only when it's applicable. This is a critical point that applies to all technology: Don't use something just because you think it's cool.

The main focus of using multiple threads is increasing application performance, so don't use multithreading until you prove to yourself (and, hopefully, others around you) that a single-threaded implementation is unacceptably slow.

Before venturing into an explicitly multithreaded mechanism, remember that Microsoft provides an apartment model that allows an object written as a single-threaded construct to run in a multithreaded environment. Therefore, you may not need to explicitly code for multithreading.

Choosing a threading model is never easy. For instance, apartment threading is faster than single threading because multiple instances of a component may be doing the work. Free threading is faster and more efficient than apartment threading in some situations because everything is happening at once and all the supplies are shared. On the other hand, this can lead to problems if multiple threads are changing shared resources.

TechRepublic's free .NET newsletter, delivered each Wednesday, contains useful tips and coding examples on topics such as Web services, ASP.NET, ADO.NET, and Visual Studio .NET. Automatically sign up today!

About Tony Patton

Tony Patton has worn many hats over his 15+ years in the IT industry while witnessing many technologies come and go. He currently focuses on .NET and Web Development while trying to grasp the many facets of supporting such technologies in a productio...

Editor's Picks