What will be the output of this C# program?
using System;
using System.Threading.Tasks;
class Program
{
static async Task Main()
{
Console.WriteLine($"Start Thread: {Environment.CurrentManagedThreadId}");
await Task.Delay(100).ConfigureAwait(false);
Console.WriteLine($"After await Thread: {Environment.CurrentManagedThreadId}");
}
}using System; using System.Threading.Tasks; class Program { static async Task Main() { Console.WriteLine($"Start Thread: {Environment.CurrentManagedThreadId}"); await Task.Delay(100).ConfigureAwait(false); Console.WriteLine($"After await Thread: {Environment.CurrentManagedThreadId}"); } }
Think about how ConfigureAwait(false) affects thread continuation.
ConfigureAwait(false) tells the await to not capture the current synchronization context. This means the continuation after await may run on a different thread, often a thread pool thread, not necessarily the original thread.
Consider a UI application where the main thread ID is 1. What will this code print?
using System;
using System.Threading.Tasks;
class Program
{
static async Task Main()
{
Console.WriteLine($"Before await Thread: {Environment.CurrentManagedThreadId}");
await Task.Delay(50).ConfigureAwait(true);
Console.WriteLine($"After await Thread: {Environment.CurrentManagedThreadId}");
}
}using System; using System.Threading.Tasks; class Program { static async Task Main() { Console.WriteLine($"Before await Thread: {Environment.CurrentManagedThreadId}"); await Task.Delay(50).ConfigureAwait(true); Console.WriteLine($"After await Thread: {Environment.CurrentManagedThreadId}"); } }
ConfigureAwait(true) captures the synchronization context.
With ConfigureAwait(true), the continuation after await runs on the original context (UI thread), so thread ID remains the same.
What problem can occur in this code snippet when ConfigureAwait(false) is not used?
public async Task LoadDataAsync()
{
await Task.Delay(1000); // Simulate data loading
UpdateUI();
}
void UpdateUI()
{
// Update UI elements here
}public async Task LoadDataAsync() { await Task.Delay(1000); // Simulate data loading UpdateUI(); } void UpdateUI() { // Update UI elements here }
Think about thread affinity for UI updates.
Without ConfigureAwait(false), the continuation tries to resume on the captured context. But if the context is lost or the method is called from a non-UI thread, UpdateUI may run on a wrong thread causing an InvalidOperationException.
Which of the following code snippets correctly uses ConfigureAwait to avoid capturing the synchronization context?
Remember ConfigureAwait is called on the task returned by the async method.
ConfigureAwait is an extension method on Task or Task<T> and must be called on the awaited task instance.
You are writing a library method that performs asynchronous work. The library should not assume the caller's synchronization context. Which ConfigureAwait usage is best practice inside your library method?
Think about library code independence from UI or synchronization contexts.
Library code should avoid capturing synchronization context to prevent deadlocks and improve performance. Using ConfigureAwait(false) is recommended.