Difference Between Synchronous and Asynchronous Programming
We have now seen both styles of programming. In this lesson we put them side by side so the difference is crystal clear.
A phone call is synchronous: while you are on the call, you are busy and must wait for the other person to answer. A WhatsApp message is asynchronous: you send it, put your phone away and do other things. When the reply comes, you read it.
Comparison table
| Point | Synchronous | Asynchronous |
|---|---|---|
| How tasks run | One after another, in a fixed order | A task is started, and the program continues without waiting for it |
| Waiting | The thread waits (is blocked) until the task finishes | The thread is released while waiting and can do other work |
| Total time for independent tasks | Sum of all task times | Close to the time of the longest task |
| User interface | Freezes during long work | Stays responsive |
| Web servers | Each waiting request holds a thread, so fewer users can be served | Threads are returned to the pool while waiting, so more users can be served |
| Code style in C# | Normal methods returning void, int, string... | async methods returning Task or Task<T>, called with await |
| Method names | ReadAllText, ExecuteReader, SaveChanges | ReadAllTextAsync, ExecuteReaderAsync, SaveChangesAsync |
| Ease of understanding | Very simple | Simple with async/await, but you must learn a few rules |
| Debugging | Easy, the call stack is straightforward | A little harder, code resumes later and maybe on another thread |
| Best for | Quick work and pure calculations | Work that waits: database, files, network, web APIs |
Side by side: reading a file
// Synchronous: the thread waits until the whole file is read
static void ShowFileSize()
{
string text = File.ReadAllText("orders.txt");
Console.WriteLine($"Characters: {text.Length}");
}
// Asynchronous: the thread is free while the disk reads the file
static async Task ShowFileSizeAsync()
{
string text = await File.ReadAllTextAsync("orders.txt");
Console.WriteLine($"Characters: {text.Length}");
}
Both methods produce the same result. The difference is what the thread does while the disk is working. In the first one it sits idle. In the second one it goes back and can do other work.
Side by side: reading from SQL Server
// Synchronous
public List<string> GetCustomerNames()
{
var names = new List<string>();
using var connection = new SqlConnection(connectionString);
connection.Open();
using var command = new SqlCommand("SELECT Name FROM Customers", connection);
using var reader = command.ExecuteReader();
while (reader.Read())
{
names.Add(reader.GetString(0));
}
return names;
}
// Asynchronous
public async Task<List<string>> GetCustomerNamesAsync()
{
var names = new List<string>();
using var connection = new SqlConnection(connectionString);
await connection.OpenAsync();
using var command = new SqlCommand("SELECT Name FROM Customers", connection);
using var reader = await command.ExecuteReaderAsync();
while (await reader.ReadAsync())
{
names.Add(reader.GetString(0));
}
return names;
}
See how similar they look. With async and await, asynchronous code reads almost exactly like synchronous code. That is the main reason these keywords exist.
Side by side: timing
// Synchronous: about 5 seconds
Thread.Sleep(2000);
Thread.Sleep(3000);
// Asynchronous, one after another: still about 5 seconds
await Task.Delay(2000);
await Task.Delay(3000);
// Asynchronous, at the same time: about 3 seconds
await Task.WhenAll(Task.Delay(2000), Task.Delay(3000));
Writing await on each line one after another does not make tasks overlap. It only frees the thread while waiting. To make independent tasks overlap, start them first and then await them together, for example with Task.WhenAll.
Which one should I choose?
- If the code waits on a database, file, network or API, use asynchronous code.
- If the code only calculates and finishes quickly, use synchronous code.
- In ASP.NET Core, controller actions that talk to a database or another service should be asynchronous.
Summary
- Synchronous: do one thing, wait for it, then do the next thing.
- Asynchronous: start a thing, do other work, and come back when it is done.
- Synchronous blocks the thread while waiting; asynchronous releases it.
- Async methods return
Task/Task<T>and their names end withAsync. - To overlap work, start the tasks first, then await them.