Isaac.

csharp

C# Async Patterns

Master async/await and asynchronous programming patterns.

By Emem IsaacFebruary 5, 20223 min read
#csharp#async#await#asynchronous#patterns
Share:

A Simple Analogy

Async is like ordering food at a restaurant. Instead of waiting at the counter, you get a number and do other things. When your food is ready (the Task completes), you pick it up.


Why Use Async?

  • Responsiveness: UI doesn't freeze during I/O
  • Scalability: Handle more concurrent requests
  • Efficiency: Don't block threads while waiting
  • Better UX: Apps feel snappier
  • Resource savings: Fewer threads = lower memory

Basic Async/Await

// Without async: Blocks thread
public string FetchData()
{
    var data = new WebClient().DownloadString("https://api.example.com/data");
    return data;
}

// With async: Non-blocking
public async Task<string> FetchDataAsync()
{
    var client = new HttpClient();
    var data = await client.GetStringAsync("https://api.example.com/data");
    return data;
}

// Usage
var result = await FetchDataAsync();

Async Patterns

// Pattern 1: Fire and forget (bad practice)
_ = LoadDataAsync(); // Ignores exceptions

// Pattern 2: Async all the way
public async Task ProcessOrderAsync(Order order)
{
    await ValidateOrderAsync(order);
    await SaveOrderAsync(order);
    await SendEmailAsync(order.Email);
}

// Pattern 3: Parallel async operations
public async Task<(Product, Reviews)> GetProductDetailsAsync(int id)
{
    var productTask = GetProductAsync(id);
    var reviewsTask = GetReviewsAsync(id);
    
    await Task.WhenAll(productTask, reviewsTask);
    
    return (productTask.Result, reviewsTask.Result);
}

// Pattern 4: Cancellation
public async Task<Data> FetchWithCancellationAsync(CancellationToken ct)
{
    var response = await httpClient.GetAsync("https://api.example.com/data", ct);
    return await response.Content.ReadAsAsync<Data>();
}

Exception Handling

// Try-catch works with async
public async Task<Order> GetOrderAsync(int id)
{
    try
    {
        return await orderService.GetAsync(id);
    }
    catch (HttpRequestException ex)
    {
        logger.LogError("API error: {0}", ex.Message);
        throw;
    }
}

// Multiple async operations with error handling
public async Task ProcessMultipleAsync(List<int> ids)
{
    var tasks = ids.Select(id => ProcessOneAsync(id)).ToList();
    
    try
    {
        await Task.WhenAll(tasks);
    }
    catch (Exception ex)
    {
        var failed = tasks.Where(t => t.IsFaulted).ToList();
        logger.LogError("Failed tasks: {0}", failed.Count);
    }
}

ValueTask for Performance

// Use Task for I/O operations
public async Task<string> FetchFromApiAsync()
{
    var response = await httpClient.GetAsync("https://api.example.com");
    return await response.Content.ReadAsStringAsync();
}

// Use ValueTask when result is often synchronous
public async ValueTask<int> GetCachedValueAsync(string key)
{
    // Often returns synchronously from cache
    if (cache.TryGetValue(key, out var value))
        return value;
    
    // Occasionally awaits database
    return await database.GetValueAsync(key);
}

Best Practices

  1. Async all the way: Make callers async too
  2. Avoid blocking: Never use .Result or .Wait()
  3. Configure await: Use ConfigureAwait(false) in libraries
  4. Handle cancellation: Accept CancellationToken
  5. Use ValueTask: When result is often synchronous

Related Concepts

  • Task vs. ValueTask performance
  • Async iterators
  • Task schedulers
  • Synchronization context
  • Async streams

Summary

C# async patterns enable responsive, scalable applications by preventing thread blocking. Master async/await to build modern, efficient applications.

Share:

Written by Emem Isaac

Expert Software Engineer with 15+ years of experience building scalable enterprise applications. Specialized in ASP.NET Core, Azure, Docker, and modern web development. Passionate about sharing knowledge and helping developers grow.

Ready to Build Something Amazing?

Let's discuss your project and explore how my expertise can help you achieve your goals. Free consultation available.

💼 Trusted by 50+ companies worldwide | ⚡ Average response time: 24 hours