Async/Await Operations
Level: Intermediate
ℹ️ What You'll Learn
- Async definition: Operation runs in background, thread freed to handle other requests (better scalability)
- Synchronous blocking:
var student = _service.GetStudent(id);blocks thread while waiting for database - Asynchronous non-blocking:
var student = await _service.GetStudentAsync(id);releases thread while waiting asynckeyword: Marks method as asynchronous (allowsawaitinside)awaitkeyword: Wait for Task to complete, but release thread to other workTask<T>return type:async Task<Student> GetStudentAsync(int id)returns result after completion- Database operations async:
await _context.Students.FirstOrDefaultAsync(s => s.Id == id)(EF Core) - HTTP calls async:
await httpClient.GetAsync("https://api.example.com/data")(external API) Task.WhenAllfor parallel:await Task.WhenAll(task1, task2, task3)run multiple operations in parallel (faster)- School Management example: Load student + teacher + exams in parallel (instead of sequential)
- Exception handling async:
try { await operation } catch { handle error }same as synchronous - Common pitfall:
.Resultblocks thread (defeats async purpose), useawaitinstead - Thread efficiency: 10,000 users on async = 1 thread, 10,000 users on sync = 10,000 threads (server crashes)
- Every Web API action should be async:
public async Task<ActionResult<Student>> GetStudent(int id)
Why Async?
Synchronous = blocks thread (slow)
Request → Database wait → Response
(thread stuck waiting)
Asynchronous = releases thread (fast)
Request → Database query in background
→ Thread handles other requests
→ Database returns → Response
Basic Async Pattern
// Synchronous (slow)
public Student GetStudent(int id)
{
return _repository.GetStudent(id); // Thread waits
}
// Asynchronous (fast)
public async Task<Student> GetStudentAsync(int id)
{
return await _repository.GetStudentAsync(id); // Thread freed
}
Controller with Async
[HttpGet("{id}")]
public async Task<ActionResult<Student>> GetStudent(int id)
{
var student = await _service.GetStudentAsync(id);
if (student == null)
return NotFound();
return Ok(student);
}
[HttpPost]
public async Task<ActionResult<Student>> CreateStudent([FromBody] Student student)
{
var result = await _service.CreateStudentAsync(student);
return CreatedAtAction(nameof(GetStudent), new { id = result.Id }, result);
}
[HttpPut("{id}")]
public async Task<ActionResult> UpdateStudent(int id, [FromBody] Student student)
{
await _service.UpdateStudentAsync(id, student);
return NoContent();
}
[HttpDelete("{id}")]
public async Task<ActionResult> DeleteStudent(int id)
{
await _service.DeleteStudentAsync(id);
return NoContent();
}
Service Layer
public class StudentService : IStudentService
{
public async Task<List<Student>> GetStudentsAsync()
{
return await _repository.GetStudentsAsync();
}
public async Task<Student> GetStudentAsync(int id)
{
return await _repository.GetStudentAsync(id);
}
public async Task CreateStudentAsync(Student student)
{
await _repository.AddAsync(student);
await _repository.SaveChangesAsync();
}
}
Multiple Async Operations
[HttpGet("{id}/details")]
public async Task<ActionResult> GetStudentDetails(int id)
{
// Parallel operations
var studentTask = _studentService.GetStudentAsync(id);
var examsTask = _examService.GetStudentExamsAsync(id);
var feesTask = _feeService.GetStudentFeesAsync(id);
await Task.WhenAll(studentTask, examsTask, feesTask);
var student = await studentTask;
var exams = await examsTask;
var fees = await feesTask;
return Ok(new { student, exams, fees });
}
Error Handling
[HttpPost]
public async Task<ActionResult<Student>> CreateStudent([FromBody] Student student)
{
try
{
var result = await _service.CreateStudentAsync(student);
return CreatedAtAction(nameof(GetStudent), new { id = result.Id }, result);
}
catch (Exception ex)
{
_logger.LogError(ex, "Error creating student");
return StatusCode(500, new { error = "Failed to create student" });
}
}
Key Takeaways
- Async = non-blocking
- Await = wait for operation
- Task = asynchronous operation
- Improves scalability
- Always use async in APIs
💡 Async Tip
All the way async. If controller is async, service must be async.
🤖Use AI to Learn Faster
Use ChatGPT, Claude, or Copilot to go deeper on Async Operations. Try these prompts:
"Why use async/await?""What's the difference between Task and Task<T>?""How do I run multiple async operations in parallel?""Quiz me on async/await"
💡 Tip: After reading this article, paste your own code into AI and ask "What could go wrong here and why?" — fastest way to find edge cases and deepen understanding.
nexcoding.in
Have questions on your tech stack, ongoing projects, or need one-to-one training?