What is Async Programming?
Async programming is a way to write code that doesn't block the main thread while waiting for time-consuming operations to complete.
Real-life Analogy
Imagine ordering food at a restaurant. Synchronous programming is like waiting at the counter for your food, unable to do anything else. Async programming is like getting a buzzer - you can sit down, check your phone, or chat with friends while waiting for your food to be ready.
Why We Need It:
- Keeps UI responsive
- Improves app performance
- Handles multiple operations simultaneously
- Better utilization of system resources
Basic Async/Await Pattern
public async Task<string> DownloadDataAsync()
{
using HttpClient client = new HttpClient();
// This doesn't block the thread while waiting
string result = await client.GetStringAsync("https://api.example.com/data");
return result;
}
// Calling the async method
async Task ProcessData()
{
string data = await DownloadDataAsync();
Console.WriteLine(data);
}
Async vs Synchronous
| Synchronous | Asynchronous |
|---|---|
| Blocks the current thread | Doesn't block the current thread |
| Simple to understand | More complex to implement |
| Inefficient for I/O operations | Efficient for I/O operations |
| Can cause UI to freeze | Keeps UI responsive |
| Easier error handling | Requires careful error handling |
When to Use Async:
- Network requests (HTTP API calls)
- File I/O operations
- Database queries
- Any operation that involves waiting
Async Flow Explained
1
Async method is called
2
Method executes until await
3
Control returns to caller
4
Awaitable operation runs in background
5
When operation completes, method resumes
Async Method Structure
// Async method signature
public async Task<ReturnType> MethodNameAsync()
{
// Synchronous part
Console.WriteLine("Starting async operation");
// Asynchronous part - doesn't block
var result = await SomeAsyncOperation();
// Continuation after await
Console.WriteLine($"Operation completed: {result}");
return result;
}
Error Handling in Async Code
Async methods use the same try-catch pattern as synchronous code, but with some important considerations.
async Task ProcessDataAsync()
{
try
{
string data = await DownloadDataAsync();
Console.WriteLine(data);
}
catch (HttpRequestException ex)
{
Console.WriteLine($"Network error: {ex.Message}");
}
catch (Exception ex)
{
Console.WriteLine($"Unexpected error: {ex.Message}");
}
}
// Async void methods should be avoided except for event handlers
async void ButtonClick(object sender, EventArgs e)
{
try
{
await ProcessDataAsync();
}
catch (Exception ex)
{
// Handle error in UI context
Console.WriteLine($"Error: {ex.Message}");
}
}
Important:
Always handle exceptions in async methods. Unhandled exceptions in async void methods can crash your application.