MSDN Documentation

.NET Framework | API Reference

System.Threading Namespace

Namespace: System.Threading
Assembly: mscorlib (in mscorlib.dll)

The System.Threading namespace provides classes and interfaces that support multi-threaded programming. Threading allows your application to perform multiple tasks concurrently. This can improve performance, responsiveness, and scalability by enabling operations to run in the background without blocking the main execution thread.

Overview

Modern applications often need to perform operations that take a significant amount of time, such as network requests, file I/O, or complex calculations. Without threading, these operations would freeze the user interface and make the application appear unresponsive. Threading enables these operations to be executed on separate threads, allowing the main thread to continue handling user input and other foreground tasks.

Key concepts in this namespace include:

  • Threads: The fundamental unit of execution within a process.
  • Synchronization Primitives: Mechanisms to control access to shared resources and prevent race conditions.
  • Thread Pooling: Reusing threads to reduce the overhead of creating and destroying them.
  • Cancellation: Cooperative mechanisms to signal that an operation should be aborted.

Key Classes

Thread Class

The Thread class represents an operating system thread. You can create and manage threads explicitly using this class. This gives you fine-grained control but also increases the complexity of managing thread lifecycles and synchronization.


using System;
using System.Threading;

public class Example
{
    public static void WorkerMethod()
    {
        Console.WriteLine("Worker thread started.");
        Thread.Sleep(2000); // Simulate work
        Console.WriteLine("Worker thread finished.");
    }

    public static void Main(string[] args)
    {
        Thread worker = new Thread(WorkerMethod);
        worker.Start(); // Start the thread

        Console.WriteLine("Main thread continues.");
        worker.Join(); // Wait for the worker thread to finish

        Console.WriteLine("Main thread exiting.");
    }
}
                

Monitor Class

The Monitor class provides static methods for obtaining mutual-exclusion locks on an object. It allows only one thread to execute a critical section of code at a time, ensuring data integrity when multiple threads access shared resources.


using System;
using System.Threading;

public class BankAccount
{
    private decimal balance = 1000;
    private readonly object balanceLock = new object();

    public void Withdraw(decimal amount)
    {
        lock (balanceLock) // Equivalent to Monitor.Enter/Exit
        {
            if (balance >= amount)
            {
                balance -= amount;
                Console.WriteLine($"Withdrawal successful. New balance: {balance}");
            }
            else
            {
                Console.WriteLine("Insufficient funds.");
            }
        }
    }
}
                

Mutex Class

A Mutex (mutual exclusion) is a synchronization primitive that can be used to synchronize access to a resource across multiple threads or processes. It's heavier than a lock and can be named, allowing synchronization between different applications.

Semaphore and SemaphoreSlim Classes

A Semaphore limits the number of threads that can access a resource or pool of resources concurrently. SemaphoreSlim is a lighter-weight version for use within a single process.

AutoResetEvent Class

An AutoResetEvent is a synchronization primitive that allows one thread to signal one or more other threads that an event has occurred. It automatically resets itself to the non-signaled state after a thread has been released.

ManualResetEvent Class

A ManualResetEvent is similar to AutoResetEvent but does not reset itself automatically. It remains in the signaled state until explicitly reset. This is useful for scenarios where multiple threads need to wait for the same event.

CountdownEvent Class

The CountdownEvent is a synchronization primitive that allows multiple threads to wait until a set of operations have completed. A thread can signal that an operation is done, and the event will be signaled when the count reaches zero.

Barrier Class

A Barrier allows multiple threads to wait at a common point (a barrier) before proceeding. All threads must reach the barrier before any can continue.

Task (System.Threading.Tasks)

While technically in the System.Threading.Tasks namespace (introduced in .NET Framework 4.0), the Task class and the Task Parallel Library (TPL) provide a higher-level abstraction for asynchronous programming, often simplifying the use of threads.

CancellationTokenSource

CancellationTokenSource is used to create and manage a CancellationToken, which can be passed to operations to signal cancellation. This is crucial for cooperative cancellation of long-running operations.

Best Practices

  • Prefer using higher-level constructs like Task Parallel Library (TPL) or async/await over direct Thread manipulation for most asynchronous operations.
  • Use synchronization primitives judiciously to avoid deadlocks and performance bottlenecks.
  • Implement cancellation mechanisms to allow users to abort long-running operations gracefully.
  • Consider thread pooling for scenarios where threads are frequently created and destroyed.
  • Thoroughly test multi-threaded applications to identify and resolve race conditions and deadlocks.