What is the difference between a Task and a Thread?
Quick Answer
A Thread is an actual OS thread — expensive to create (~1 MB stack), you manage its lifetime. A Task is a higher-level promise of future work or a future result; it's usually scheduled onto the shared thread pool, may not use a dedicated thread at all (I/O tasks), and composes with async/await, continuations and cancellation.
A Thread is a real operating-system thread — it's expensive, has its own stack, and I'm responsible for it. A Task is an abstraction: a promise that some work will finish and maybe produce a result. Most tasks run on the thread pool, and I/O-bound tasks don't tie up a thread at all while they wait. Tasks compose — I can await them, chain continuations, cancel them with a token. So my default is Task: Task.Run for CPU work, async methods for I/O. I only create a raw Thread for a long-running dedicated loop that shouldn't hog a pool thread.
| Thread | Task | ||
|---|---|---|---|
| Abstraction level | OS thread | Unit of work / future result | |
| Cost | High (stack, kernel object) | Low (pooled) | |
| Returns a result | No (awkward) | Yes (Task<T>) | |
| Continuations / await | No | Yes | |
| Cancellation | Manual / unsafe abort | CancellationToken | |
| I/O without a thread | No | Yes |
Use Task.Run to offload CPU-bound work to the pool; use async methods returning Task for I/O (no thread held while waiting). Reach for a raw Thread only for long-running dedicated work that shouldn't sit on the pool, or when you need specific thread settings (priority, apartment state, a bigger stack).