Threading  

Top 10 TPL (Task Parallel Library) Interview Questions with Examples

What is TPL?

TPL (Task Parallel Library) is a .NET library introduced in .NET Framework 4.0 to simplify parallel and asynchronous programming.

Instead of manually creating and managing threads, TPL provides abstractions such as:

  • Task

  • Task

  • Parallel.For

  • Parallel.ForEach

  • Task.WhenAll

  • Task.WhenAny

Example

Task.Run(() =>
{
    Console.WriteLine("Running in background");
});

Interview Answer

TPL is a .NET library that provides a higher-level abstraction for concurrent and parallel programming. It simplifies multithreading by using Tasks instead of manually managing threads.

Difference Between Task and Thread

Thread

Thread thread = new Thread(() =>
{
    Console.WriteLine("Thread");
});

thread.Start();

Characteristics

  • OS-managed

  • Expensive to create

  • Dedicated execution path

Task

await Task.Run(() =>
{
    Console.WriteLine("Task");
});

Characteristics

  • Managed by TPL

  • Usually uses ThreadPool

  • Lightweight

  • Supports async/await

Interview Answer

A Thread is a low-level OS execution unit, while a Task is a high-level abstraction representing asynchronous work. Tasks are lightweight, scalable, and generally preferred over creating threads directly.

What is Task.Run()?

Task.Run() schedules work on a ThreadPool thread.

Example

await Task.Run(() =>
{
    Console.WriteLine(
        $"Thread Id = {Thread.CurrentThread.ManagedThreadId}");
});

Internally

Task.Run()
      ↓
ThreadPool
      ↓
Worker Thread

Use Cases

  • ✅ CPU-bound operations

  • ✅ Background processing

  • ✅ Calculations

What is Task.WhenAll()?

Used to wait for multiple tasks to complete.

Example

var userTask = GetUsersAsync();
var orderTask = GetOrdersAsync();

await Task.WhenAll(userTask, orderTask);

Sequential Execution

await GetUsersAsync();
await GetOrdersAsync();
2 sec + 2 sec = 4 sec

Concurrent Execution

await Task.WhenAll(
    GetUsersAsync(),
    GetOrdersAsync());
≈ 2 sec

Interview Answer

Task.WhenAll executes multiple independent tasks concurrently and waits until all tasks complete.

What is Task.WhenAny()?

Returns when the first task completes.

Example

var task1 = Task.Delay(3000);
var task2 = Task.Delay(1000);

Task first =
    await Task.WhenAny(task1, task2);

Console.WriteLine("First Task Completed");

Output

First Task Completed

after 1 second.

Use Cases

  • ✅ Timeout handling

  • ✅ Fastest response wins

  • ✅ Multi-server requests

What is CancellationToken?

Used to cancel a running task gracefully.

Example

var cts = new CancellationTokenSource();

Task task = Task.Run(() =>
{
    while (!cts.Token.IsCancellationRequested)
    {
        Console.WriteLine("Working...");
    }
}, cts.Token);

cts.Cancel();

Real-world Use Cases

  • ✅ API request cancellation

  • ✅ Background service shutdown

  • ✅ Long-running operations

Interview Answer

CancellationToken provides a cooperative cancellation mechanism for asynchronous operations and tasks.

How Does TPL Use ThreadPool?

Most Tasks execute on ThreadPool threads.

Example

Task.Run(() =>
{
    Console.WriteLine(
        Thread.CurrentThread.IsThreadPoolThread);
});

Output

True

Workflow

Task Created
      ↓
Queued To ThreadPool
      ↓
Worker Thread Executes Task
      ↓
Thread Returned To Pool

Benefits

  • ✅ Thread reuse

  • ✅ Lower memory usage

  • ✅ Better scalability

Difference Between Parallel.ForEach and Task.WhenAll()

This is a very popular interview question.

Parallel.ForEach

Best for:

CPU-bound Work

Example

Parallel.ForEach(files, file =>
{
    ProcessFile(file);
});

Use Cases

  • Image processing

  • Encryption

  • PDF generation

Task.WhenAll

Best for:

I/O-bound Work

Example

await Task.WhenAll(
    GetCustomerAsync(),
    GetOrdersAsync());

Use Cases

  • API calls

  • Database requests

  • File downloads

Interview Answer

Parallel.ForEach is designed for CPU-intensive operations and uses multiple cores. Task.WhenAll is used for coordinating multiple asynchronous I/O operations.

What is Task?

A Task represents an asynchronous operation that may complete in the future.

Task

public async Task SaveAsync()
{
    await Task.Delay(1000);
}

Returns:

No Result

Task

public async Task<int> GetCountAsync()
{
    return 100;
}

Returns:

Result

Usage

int result = await GetCountAsync();

Interview Answer

Task represents asynchronous work, while Task represents asynchronous work that returns a value.

How Does async/await Relate to TPL?

async/await is built on top of Task and TPL.

Example

public async Task<string> GetDataAsync()
{
    await Task.Delay(2000);

    return "Success";
}

Usage

string result =
    await GetDataAsync();

Console.WriteLine(result);

Output

Success

Behind the Scenes

async/await
      ↓
Task
      ↓
TPL
      ↓
ThreadPool (when needed)

Real Example

Without async/await:

Task<string> task =
    GetDataAsync();

task.Wait();

Console.WriteLine(task.Result);

Not recommended.

With async/await:

string result =
    await GetDataAsync();

Console.WriteLine(result);

Cleaner and non-blocking.

Interview Answer

async/await is language support built on top of the Task Parallel Library. Async methods return Task or Task, and await is used to asynchronously wait for task completion without blocking the current thread.

Summary

TPL is the foundation of modern .NET asynchronous and parallel programming, with Task being the core abstraction that powers async/await, concurrency, and scalable applications. It provides higher-level constructs such as Task, Task<T>, Task.WhenAll, Task.WhenAny, and Parallel.ForEach to simplify concurrent programming while leveraging the ThreadPool for efficient resource utilization. Understanding these concepts is essential for building responsive, high-performance .NET applications and for answering common .NET interview questions.