dotnet --version
Build a console app demonstrating ConfigureAwait, Task.WhenAll, CancellationToken, and avoiding async deadlocks.
1 using System; 2 using System.Collections.Generic; 3 using System.Net.Http; 4 using System.Threading; 5 using System.Threading.Tasks; 6 7 public class AsyncPatterns 8 { 9 private static readonly HttpClient _http = new(); 10 11 // Pattern 1: Concurrent requests with Task.WhenAll 12 public static async Task<string[]> FetchAllAsync( 13 IEnumerable<string> urls, 14 CancellationToken ct = default) 15 { 16 var tasks = urls.Select(url => FetchAsync(url, ct)); 17 return await Task.WhenAll(tasks).ConfigureAwait(false); 18 } 19 20 // Pattern 2: ConfigureAwait(false) in library code 21 private static async Task<string> FetchAsync(string url, CancellationToken ct) 22 { 23 using var response = await _http.GetAsync(url, ct).ConfigureAwait(false); 24 response.EnsureSuccessStatusCode(); 25 return await response.Content.ReadAsStringAsync(ct).ConfigureAwait(false); 26 } 27 28 // Pattern 3: IAsyncEnumerable for streaming results 29 public static async IAsyncEnumerable<string> StreamResultsAsync( 30 IEnumerable<string> urls, 31 [System.Runtime.CompilerServices.EnumeratorCancellation] CancellationToken ct = default) 32 { 33 foreach (var url in urls) 34 { 35 ct.ThrowIfCancellationRequested(); 36 string result = await FetchAsync(url, ct).ConfigureAwait(false); 37 yield return result; 38 } 39 } 40 41 // Pattern 4: Timeout via CancellationTokenSource 42 public static async Task RunWithTimeoutAsync(Func<CancellationToken, Task> work) 43 { 44 using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(5)); 45 try 46 { 47 await work(cts.Token).ConfigureAwait(false); 48 } 49 catch (OperationCanceledException) 50 { 51 Console.WriteLine("Operation timed out after 5 seconds."); 52 } 53 } 54 } 55
Sign in to share your feedback and join the discussion.