Let’s go through Task and Task<T> in C# β€” the foundation of asynchronous programming and parallel operations.


πŸ“Œ 1. What is a Task?

  • A Task represents an operation that may run in the background. The key here is that this operation may or may not be asynchronous.

  • Part of the System.Threading.Tasks namespace.

  • Can be used to run code asynchronously, wait for completion, or return results.


πŸ“Œ 2. Task vs Task<T>

TypeDescription
TaskRepresents an asynchronous operation with no return value
Task<T>Represents an asynchronous operation that returns a value of type T

πŸ“Œ 3. Creating a Task

Task without return value

using System;
using System.Threading.Tasks;
 
Task task = Task.Run(() =>
{
    Console.WriteLine("Task running...");
    Task.Delay(1000).Wait(); // Simulate work
    Console.WriteLine("Task completed");
});
 
task.Wait(); // Wait for completion
  • Task.Run starts the task on a thread pool thread

  • Wait() blocks until task finishes


Task with return value (Task<T>)

Task<int> task = Task.Run(() =>
{
    Task.Delay(1000).Wait(); // Simulate work
    return 42;
});
 
int result = task.Result; // Get the result
Console.WriteLine(result); // 42
  • Task<T> allows returning a value from the async operation

  • Access result via .Result (blocking) or await (non-blocking)


πŸ“Œ 4. Using await with Tasks

async Task<int> CalculateAsync()
{
    await Task.Delay(1000); // Simulate work
    return 100;
}
 
int result = await CalculateAsync();
Console.WriteLine(result); // 100
  • Preferred approach over .Result for non-blocking calls

πŸ“Œ 5. Waiting for Multiple Tasks

Task<int> t1 = Task.Run(() => 10);
Task<int> t2 = Task.Run(() => 20);
 
int[] results = await Task.WhenAll(t1, t2);
Console.WriteLine($"Sum: {results[0] + results[1]}"); // Sum: 30
  • Task.WhenAll waits for all tasks

  • Task.WhenAny waits for the first task to complete


πŸ“Œ 6. Exception Handling in Tasks

try
{
    Task task = Task.Run(() => throw new Exception("Error in task"));
    await task;
}
catch (Exception ex)
{
    Console.WriteLine($"Caught: {ex.Message}");
}
  • Use try-catch around await to handle exceptions

  • Exceptions in tasks propagate when awaited


πŸ“Œ 7. Summary Table

FeatureDescription
TaskRepresents async operation, no return value
Task<T>Represents async operation returning a value
CreationTask.Run(() => ...)
Awaitingawait task (non-blocking)
Waitingtask.Wait() (blocking)
Multiple TasksTask.WhenAll, Task.WhenAny
Exception HandlingUse try-catch around await

βœ… Tip:

  • Use Task for background operations

  • Use Task when you need a result from asynchronous work

  • Combine with async/await for clean, non-blocking code