CHAPTER 24
Beginner
Multithreading and Async Programming in C#
Updated: May 17, 2026
5 min read
# CHAPTER 24
Multithreading and Async Programming
1. Introduction
If you build a desktop app and tell it to download a 5GB file on the main thread, the entire application will freeze. The buttons won't click, and Windows will say "Not Responding." Why? Because a thread can only do one thing at a time. Async Programming allows your application to offload heavy work to the background, keeping the user interface perfectly responsive.2. Learning Objectives
By the end of this chapter, you will be able to:- Understand the difference between Synchronous and Asynchronous execution.
-
Use the Task Parallel Library (
Task).
-
Master the
asyncandawaitkeywords.
- Prevent application freezing.
3. The Problem: Synchronous Execution
Synchronous code runs line by line. Line 2 cannot start until Line 1 finishes.
csharp
4. The Solution: Task and async/await
Introduced in C# 5.0, the async and await keywords revolutionized asynchronous programming. They use the Task Parallel Library (TPL) to effortlessly run code in the background.
csharp
5. Returning Data from Async Methods
If an async method needs to return an integer, it returns aTask<int>.
csharp
6. Threads vs. Tasks
-
Thread(Legacy): A low-level OS thread. Heavy to create. Managing them manually (locking, deadlocks) is extremely difficult.
-
Task(Modern): A higher-level abstraction. The .NET Thread Pool manages tasks automatically, assigning them to available threads efficiently. Always use Tasks in modern C#.
7. Concurrency vs Parallelism
- Concurrency (async/await): The program juggles multiple tasks. While waiting for a network response, the thread goes and updates the UI instead of sitting idle.
-
Parallelism (
Parallel.ForEach): The program explicitly uses multiple CPU cores to do complex math equations at the exact same time.
8. Common Mistakes
-
async void: NEVER writeasync void MethodName()unless it is an Event Handler (like a button click). If anasync voidmethod throws an exception, it crashes the entire application. Always useasync Task.
-
Forgetting
await: If you call an async method but forget theawaitkeyword, the method will start running, but the code will immediately move to the next line without waiting for the result. This causes unpredictable bugs.
9. Best Practices
-
Append the word
Asyncto the name of any method that returns a Task (e.g.,SaveToDbAsync()). This is a Microsoft standard convention.
-
Use
awaitall the way down the call stack. Do not mix synchronous blocking (.Resultor.Wait()) with async code, as this causes Deadlocks.
10. Exercises
-
1.
Write an async method
BoilWaterAsync()that waits for 3 seconds.
-
2.
In
Main, startBoilWaterAsync(), print "Chopping vegetables...", and thenawaitthe water.
11. MCQs with Answers
Question 1
What happens if a heavy 10-second database query is run synchronously on the UI thread?
Question 2
Which two keywords define modern asynchronous programming in C#?
Question 3
What return type should an async method have if it doesn't return any data?
Question 4
What return type should an async method have if it returns a string?
Question 5
When is it acceptable to use async void?
Question 6
What does the await keyword do?
Question 7
What is the modern, preferred alternative to manually creating new Thread()?
Question 8
What is the asynchronous equivalent of Thread.Sleep(1000)?
Question 9
What happens if you forget to await an async method?
Question 10
What naming convention should be applied to async methods?
12. Interview Questions
-
Q: Explain what
async/awaitdoes under the hood (State Machine).
-
Q: Why is
async voidconsidered dangerous?
-
Q: Explain the difference between CPU-bound work (Parallelism) and I/O-bound work (Concurrency). Which is
async/awaitbetter suited for?
13. Summary
Asynchronous programming ensures your application remains responsive during heavy I/O operations (file writing, network requests, database queries). By marking methodsasync Task and using await, C# abstracts away the immense complexity of threading, allowing you to write background operations that look and read like normal synchronous code.