There is only one namespace that you need to handle threading: System::Threading. What you plan to do while using the threads will determine which of the classes you will use. Many of the classes provide different ways to do the same thing, usually differing in the degree of control. Here is a list of some of the more common classes within the System::Threading namespace:
AutoResetEvent notifies a waiting thread that an event has occurred. You use this class to allow communication between threads using signaling. Typically, you use this class for threads that need exclusive access.
Interlocked allows for atomic operation on a variable that is shared between threads.
ManualResetEvent notifies one or more threads that an event has occurred. You use this class to allow communication between threads using signaling. Typically, you use this class for scenarios where one thread must complete before other threads can proceed.
Monitor provides a mechanism to synchronize access to objects by locking access to a block of code, commonly called a critical section. While a thread owns the lock for an object, no other thread can acquire that lock.
Mutex provides a synchronization primitive that solves the problem of two or more threads needing access to a shared resource at the same time. It ensures that only one thread at a time uses the resource. This class is similar in functionality to Monitor, except Mutex allows for interprocess synchronization.
ReaderWriterLock allows a single writer and multiple readers access to a resource. At any given time, it allows either concurrent read access for multiple threads or write access to a single thread.
Thread is the core class to create a thread to execute a portion of the program code.
ThreadPool provides access to a pool of system-maintained threads.
WaitHandle allows for the taking or releasing of exclusive access to a shared system-specific resource.
From the preceding list of classes, you can see that the .NET Framework class library provides two ways to create threads:
The difference between the two primarily depends on whether you want to maintain the Thread object or you want the system to handle it for you. In effect, nearly the same results can be achieved with either method. I cover Thread first, as it provides you with complete control of your threads. Later in this chapter, I cover ThreadPool, where the system maintains the process threads. Though, even with this reduction in control, you will see later in the chapter that ThreadPools can be used just as effectively as Threads. But, before you cover either method, you'll take a look at thread state and priority.