WHYOLOGYLog in
no ads · no distractions

Become a better
.NET backend engineer
in 5 minutes a day.

Swipeable cards. First principles. Real C# code. Every topic — from async/await to system design — built to make you a stronger .NET developer, ready for the interview and the job.

.NET & C#AI & ML Interview Prep

Already learning? Log in · Open the app

Every lesson is free. ₹99/year unlocks unlimited bookmarks, tagging & deep search.

25+Topics live
400+Swipe cards
100+Interview Qs

See how you'll learn

Every topic, broken into bite-sized cards

Understand
3 min read

Why Do We Need Async/Await?

A synchronous API call blocks the thread for the entire duration of I/O — file reads, DB calls, HTTP requests — wasting a thread that could serve another request.

A web server has a limited thread pool. If every request blocks a thread while waiting on a database call, the server runs out of threads under load and starts queuing or rejecting requests.

Async/await frees the thread during the wait, so it can serve other requests, then resumes your code when the I/O completes.
Understand
2 min read

A Waiter, Not a Cook

A synchronous waiter takes your order, stands at the kitchen window until it’s ready, then serves you — no other tables get attention meanwhile.

Real-world analogy

An async waiter takes your order, hands it to the kitchen, and immediately serves other tables. When your food is ready, they come back to you. Same waiter, many tables — no one blocked.

Understand
3 min read

Why Was the Task-Based Async Pattern Created?

Before async/await, scaling I/O-bound code meant manual callbacks or the APM pattern (BeginXxx/EndXxx) — hard to read, hard to compose, easy to get wrong.
  • Frees threads during I/O instead of blocking them
  • Reads like sequential code instead of nested callbacks
  • Composable with Task.WhenAll / Task.WhenAny
Understand
2 min read

What Is Async/Await, Really?

async/await is syntactic sugar over the Task-based Asynchronous Pattern (TAP).

The compiler rewrites your method into a state machine that can pause at each await and resume later — without blocking a thread while paused.

Key types: Task, Task<T>, ValueTask<T>, SynchronizationContext, TaskScheduler.
Learn
4 min read

What Actually Happens at "await"

  1. Method runs synchronously up to the first await.
  2. If the awaited Task isn’t complete, the method returns control to its caller immediately — the thread is freed.
  3. The compiler-generated state machine registers a continuation on the Task.
  4. When the I/O completes, the continuation resumes the method — on the captured SynchronizationContext, if one exists.
The thread that resumes your code after await is often NOT the same thread that started the method — async does not mean "runs on the same thread."
Learn
4 min read

Task vs Thread vs ThreadPool

ThreadTask
OS-level, expensive to createLightweight abstraction over work
Always occupies a thread while runningCan be I/O-bound and hold no thread while waiting
Manual lifecycle managementComposable via async/await, WhenAll, ContinueWith
Task.Run queues CPU-bound work to the ThreadPool. await on I/O (HttpClient, EF Core, file streams) doesn’t use a thread at all while waiting.
Build
3 min read

A Correct Async Call Chain

public async Task<Order> GetOrderAsync(int id)
{
  var order = await _db.Orders
    .FindAsync(id)
    .ConfigureAwait(false);

  if (order is null)
    throw new NotFoundException(id);

  return order;
}
ConfigureAwait(false) in library code avoids capturing the SynchronizationContext — one of the most common interview follow-ups.
Avoid Problems
3 min read

Pitfalls to Avoid

  • Calling .Result or .Wait() on a Task from a UI/ASP.NET context — classic deadlock
  • Using async void instead of async Task (can’t be awaited, exceptions crash the process)
  • Wrapping already-async code in Task.Run unnecessarily
  • Forgetting ConfigureAwait(false) in library/shared code
Rule of thumb: async all the way down. Once you go async, don’t block synchronously anywhere in the call chain.
Interview
2 min read

Why does calling .Result cause a deadlock?

Wait() synchronously blocks the current thread while it waits for the async method to complete.

Ideal answer: The async method captures the current SynchronizationContext and tries to resume on it after the await. But that context’s thread is blocked waiting on .Result — so the continuation can never run. Both sides wait forever. Fix: use await instead of .Result, or ConfigureAwait(false) to avoid capturing the context.
Interview
2 min read

What does ConfigureAwait(false) actually do?

NET Core?

Ideal answer: It tells the awaiter not to resume on the original SynchronizationContext, avoiding the deadlock risk and a small perf cost. ASP.NET Core has no SynchronizationContext by default, so it matters less there, but it’s still good practice in reusable/library code that might run in a context that has one.
Mentioning that ASP.NET Core removed the SynchronizationContext shows real depth beyond a memorized rule.
Interview
2 min read

async void vs async Task — why does it matter?

When should you use async void, and why is it dangerous everywhere else?

Ideal answer: async void should only be used for top-level event handlers (e.g. button clicks), because the caller has no Task to await or observe. Exceptions thrown in an async void method can’t be caught by the caller — they propagate directly to the SynchronizationContext and can crash the app. Everywhere else, use async Task.
Practice
2 min read

Check Your Understanding

  • 1. Why does .Result cause a deadlock in ASP.NET/WPF apps?
  • 2. What does ConfigureAwait(false) prevent?
  • 3. Why is async void dangerous outside event handlers?
Revision
1 min read

Key Takeaways

Interview Mantra: "Never block on async code — await it, don’t .Result it. Async all the way down."
  • await frees the thread during I/O; it doesn’t create a new thread.
  • .Result / .Wait() risk deadlocks by blocking the SynchronizationContext.
  • Use ConfigureAwait(false) in library code; avoid async void except for event handlers.
swipe to try it
Built for busy developers
Focused on what actually matters
Every lesson free — no paywall on learning