C sharp - Threading in C# – Working with Multiple Threads
Threading in C# – Working with Multiple Threads
1. What is a Thread?
-
A thread is the smallest unit of execution in a program.
-
By default, every C# program starts with one thread (the main thread).
-
Threading allows you to do multiple tasks at the same time (concurrency).
Example:
-
Main thread is running the UI.
-
Another thread downloads data in the background.
-
Another thread processes that data.
2. Creating Threads
C# provides several ways to create and manage threads.
a) Using Thread class
using System;
using System.Threading;
class Program
{
static void PrintNumbers()
{
for (int i = 1; i <= 5; i++)
{
Console.WriteLine($"Number: {i}");
Thread.Sleep(500); // pause for half a second
}
}
static void Main()
{
Thread t1 = new Thread(PrintNumbers); // create new thread
t1.Start(); // run method in separate thread
Console.WriteLine("Main thread continues...");
}
}
-
Here,
PrintNumbersruns on a separate thread, while the main thread keeps going.
b) Using Lambda Expression
Thread t2 = new Thread(() =>
{
Console.WriteLine("Thread running with lambda expression.");
});
t2.Start();
c) Using ThreadPool
-
Instead of creating threads manually, use the ThreadPool for lightweight, short-lived tasks.
ThreadPool.QueueUserWorkItem(state =>
{
Console.WriteLine("Thread from ThreadPool.");
});
3. Thread Synchronization
When multiple threads work on shared data, you must prevent conflicts.
Problem: Race Condition
int counter = 0;
void Increment()
{
for (int i = 0; i < 1000; i++)
{
counter++; // multiple threads may corrupt this
}
}
Solution: lock keyword
object lockObj = new object();
int counter = 0;
void Increment()
{
for (int i = 0; i < 1000; i++)
{
lock (lockObj)
{
counter++;
}
}
}
-
lockensures only one thread enters that block at a time.
4. Foreground vs Background Threads
-
Foreground threads: Keep running until they finish, even if the main program ends.
-
Background threads: Stop automatically when the main program ends.
Thread t = new Thread(PrintNumbers);
t.IsBackground = true; // runs as background thread
t.Start();
5. Modern Alternative: Tasks
In modern C#, instead of raw Thread, we often use Task and async/await (built on top of threading).
using System.Threading.Tasks;
await Task.Run(() =>
{
Console.WriteLine("Running task in background.");
});
6. Best Practices
-
Prefer Tasks and async/await over raw
Threadfor most cases. -
Use
lock,Monitor, orMutexto avoid race conditions. -
Don’t create too many threads manually — use
ThreadPoolorTaskfor efficiency.