20 questions found
What do async and await do?
Beginner
await asynchronously waits for a Task, releasing the thread until it completes, then resumes the method; async marks a method that uses await and returns a Task.
public async Task<string> LoadAsync(HttpClient h) => (await h.GetStringAsync("/x")).Trim();
Real-world example
A web server frees the request thread during a DB call so it can serve other requests.
What is the difference between Task and Task<T>?
Beginner
Task represents async work with no result; Task<T> completes with a value of type T that you get by awaiting it.
Task done = Task.Delay(100);
Task<int> n = Task.FromResult(42);
int v = await n;
Real-world example
Returning Task<Order> from a repository so callers can await the fetched order.
How do you run multiple async operations concurrently?
Intermediate
Start the tasks without awaiting each immediately, then await Task.WhenAll to run them in parallel and wait for all.
var t1 = h.GetStringAsync(a);
var t2 = h.GetStringAsync(b);
var r = await Task.WhenAll(t1, t2);
Real-world example
Fetching price, stock and reviews at once to cut page latency.
What does ConfigureAwait(false) do?
Intermediate
It resumes the continuation without capturing the synchronization context, avoiding a needless hop and reducing deadlocks. Use it in library code that doesn't touch UI/HttpContext.
var body = await h.GetStringAsync(url).ConfigureAwait(false);
Real-world example
A reusable NuGet library uses it so apps that block on it don't deadlock.
Why can .Result or .Wait() deadlock, and what's the fix?
Advanced
In a single-threaded context the blocked thread waits for a continuation that needs that same thread — neither proceeds. Fix by awaiting all the way down.
// risky: var d = LoadAsync().Result;
var d = await LoadAsync();
Real-world example
A legacy MVC action blocking on an async call hangs under load until made async end-to-end.
How do you design for scalability and avoid thread-pool starvation?
Advanced
Use async I/O so request threads return to the pool while waiting; never block on async (sync-over-async) as it holds threads and starves the pool under load.
public async Task<IActionResult> Get() => Ok(await _repo.GetAsync());
Real-world example
Removing blocking .Result calls let a checkout API handle far more concurrent users.
What do the 'async' and 'await' keywords do, and how do they relate to each other?
Beginner
'async' marks a method as containing asynchronous operations, enabling the use of 'await' inside it; 'await' pauses the method's execution (without blocking the calling thread) until the awaited Task completes, then resumes execution with the result.
async Task<string> FetchDataAsync() {
HttpClient client = new HttpClient();
string result = await client.GetStringAsync("https://api.example.com/data");
return result;
}
Real-world example
Fetching data from a web API or database without blocking the UI thread or a server's request-handling thread.
Common follow-ups: What does an async method's method signature typically return, and why not just 'void'?
Delegates
Events & Lambdas
Why does calling .Result or .Wait() on a Task risk causing a deadlock, particularly in ASP.NET (non-Core) or UI applications?
Intermediate
Synchronously blocking on a Task (.Result/.Wait()) while the current SynchronizationContext only allows one thread to run at a time can deadlock: the blocked thread waits for the async operation to complete, but that operation's continuation is trying to resume on the SAME captured context, which is stuck waiting — neither can proceed.
// Risky: can deadlock in ASP.NET / WinForms / WPF
string result = FetchDataAsync().Result;
// Safe: properly asynchronous all the way up
string result2 = await FetchDataAsync();
Real-world example
Debugging a mysterious application hang traced back to a synchronous .Result call inside a legacy ASP.NET MVC controller action.
Common follow-ups: Why doesn't this same deadlock risk apply to ASP.NET Core or console applications by default?
Exception Handling
What does ConfigureAwait(false) do, and when is it appropriate to use?
Intermediate
ConfigureAwait(false) tells the awaited Task NOT to resume its continuation on the original captured SynchronizationContext — appropriate in library code that doesn't need to run back on a specific UI/request context, improving performance and avoiding deadlock risk; generally unnecessary (and often omitted) in modern ASP.NET Core, which has no SynchronizationContext by default.
public async Task<string> FetchDataAsync() {
var result = await httpClient.GetStringAsync(url).ConfigureAwait(false);
return result.ToUpper(); // this line doesn't need the original context
}
Real-world example
Using ConfigureAwait(false) throughout a reusable class library (like a NuGet package) that could be consumed by both UI and server applications.
Common follow-ups: Why is ConfigureAwait(false) generally considered unnecessary boilerplate in modern ASP.NET Core code specifically?
Exception Handling
How do you run multiple asynchronous operations concurrently and wait for all of them using Task.WhenAll?
Intermediate
Start each async operation WITHOUT awaiting immediately (collecting the resulting Task objects), then await Task.WhenAll(tasks) once — this runs all operations CONCURRENTLY rather than sequentially, since each one begins executing the moment it's called, not when it's awaited.
Task<string> task1 = FetchUserAsync(1);
Task<string> task2 = FetchUserAsync(2);
Task<string> task3 = FetchUserAsync(3);
string[] results = await Task.WhenAll(task1, task2, task3); // all three run concurrently
Real-world example
Fetching data for three independent API calls simultaneously instead of sequentially awaiting each one, cutting total wait time significantly.
Common follow-ups: How does Task.WhenAll handle it if ONE of the tasks throws an exception while others are still running?
Exception Handling