← Back to Articles         
What is asynchronous programming in C#?

What is asynchronous programming in C#?

Published on 12 Oct 2026     4 min read C#
Asynchronous Programming (Async/Await)
 

Asynchronous Programming in C#

1. What is asynchronous programming in C#?

Asynchronous programming is a programming technique that allows an application to perform time-consuming operations without blocking the calling thread while waiting for those operations to complete.

In C#, asynchronous programming is primarily implemented using:

  • async – Declares a method that can use await.

  • await – Asynchronously waits for an operation to complete without blocking the thread.

  • Task – Represents an asynchronous operation that does not return a value.

  • Task<T> – Represents an asynchronous operation that returns a value.

Asynchronous programming is particularly useful for I/O-bound operations, such as database queries, API calls, file operations, and network requests.

2. Why do we need asynchronous programming?

Consider an ASP.NET Core Web API application that retrieves customer details from SQL Server.

A database query takes 3 seconds to complete.

Synchronous programming

Client Request
      |
      v
Web API Controller
      |
      v
Thread executes database query
      |
      v
Thread BLOCKED (waiting 3 seconds)
      |
      v
Database returns result
      |
      v
Thread processes result
      |
      v
Response to Client

Problem: The thread remains blocked while waiting for the database response.

If many requests arrive simultaneously, the application may require more threads, increasing resource consumption and reducing scalability.

Asynchronous programming

Client Request
      |
      v
Web API Controller
      |
      v
Start async database query
      |
      v
await database operation
      |
      v
Thread released to Thread Pool
      |
      +------> Can serve other requests
      |
      v
Database operation completes
      |
      v
Continuation resumes
(on an available thread)
      |
      v
Response to Client

Advantage: The thread is not blocked during the database wait and can be used for other work.

Important: Asynchronous programming does not necessarily make an individual database query faster. Its primary advantage is improving application responsiveness and scalability.

 

3. Example program using async and await

Consider an application that retrieves customer information.

Complete C# example

using System;
using System.Threading.Tasks;

class Program
{
    static async Task Main()
    {
        Console.WriteLine("Application Started");

        Task<string> customerTask = GetCustomerAsync();

        Console.WriteLine("Doing other work...");

        string customer = await customerTask;

        Console.WriteLine($"Customer: {customer}");

        Console.WriteLine("Application Completed");
    }

    static async Task<string> GetCustomerAsync()
    {
        Console.WriteLine("Fetching customer...");

        await Task.Delay(3000);

        return "Syed Mohamed";
    }
}

Output

Application Started
Fetching customer...
Doing other work...
Customer: Syed Mohamed
Application Completed

The application takes approximately 3 seconds to complete because Task.Delay(3000) simulates a 3-second asynchronous operation.

Step-by-step program explanation

Step 1: Application starts

Console.WriteLine("Application Started");

Displays the first message.

Step 2: Start asynchronous operation

Task<string> customerTask = GetCustomerAsync();
  • Calls GetCustomerAsync().

  • The method starts executing immediately.

  • When it reaches an incomplete await, it suspends execution.

  • The caller receives a Task<string> representing the pending result.

Step 3: Continue other work

Console.WriteLine("Doing other work...");

The calling method continues executing while the asynchronous delay is pending.

Step 4: Await the result

string customer = await customerTask;
  • Checks whether the task has completed.

  • If incomplete, suspends the calling method without blocking its thread.

  • When the task completes, execution continues and retrieves the customer name.

Step 5: Display the result

Console.WriteLine($"Customer: {customer}");

Prints the customer information.

Execution flow

Main()
  |
  |-- Print "Application Started"
  |
  |-- Call GetCustomerAsync()
  |       |
  |       |-- Print "Fetching customer..."
  |       |
  |       |-- await Task.Delay(3000)
  |       |
  |       |-- Suspend GetCustomerAsync()
  |       |
  |       +-- Return incomplete Task<string>
  |
  |-- Print "Doing other work..."
  |
  |-- await customerTask
  |       |
  |       |-- Suspend Main()
  |       |
  |       |   (3 seconds elapse)
  |       |
  |       |-- GetCustomerAsync() resumes
  |       |
  |       |-- Return "Syed Mohamed"
  |       |
  |       +-- Main() resumes
  |
  |-- Print customer
  |
  +-- Application Completed
 

4. Difference between synchronous and asynchronous programming

Feature

Synchronous

Asynchronous

Execution

Waits for operation

Can continue other work

Thread

Blocked during wait

Not blocked during asynchronous wait

Keywords

Normal method calls

async, await

Return type

void, T

Task, Task<T>

Scalability

Lower for high-concurrency I/O

Better for high-concurrency I/O

Common usage

Simple operations, CPU work

Database, API, file I/O

Synchronous example

public string GetCustomer()
{
    Thread.Sleep(3000);

    return "Syed Mohamed";
}

Thread.Sleep() blocks the current thread for 3 seconds.

Asynchronous example

public async Task<string> GetCustomerAsync()
{
    await Task.Delay(3000);

    return "Syed Mohamed";
}

Task.Delay() creates a non-blocking asynchronous delay.

 

← Back to Articles