Swiftorial Logo
Home
Swift Lessons
Matchups
CodeSnaps
Tutorials
Career
Resources

Async and Await in C#

Introduction

Asynchronous programming is essential for modern applications to ensure responsiveness and efficient performance. In C#, the async and await keywords simplify asynchronous programming by allowing you to write code that looks synchronous but performs asynchronously.

What is Asynchronous Programming?

Asynchronous programming allows a program to perform tasks without waiting for other tasks to complete. This is particularly useful for I/O-bound and network-bound operations that can take an indeterminate amount of time to complete.

Understanding Async and Await

The async keyword is used to designate a method as asynchronous. The await keyword is used to pause the execution of an async method until the awaited task completes.

Basic Example

Let's start with a basic example where we use async and await to perform an asynchronous operation:

using System;
using System.Threading.Tasks;

class Program
{
    static async Task Main(string[] args)
    {
        Console.WriteLine("Starting async method...");
        await AsyncMethod();
        Console.WriteLine("Async method completed.");
    }

    static async Task AsyncMethod()
    {
        await Task.Delay(2000); // Simulate a delay
        Console.WriteLine("Inside async method.");
    }
}
Starting async method...
// (2 second delay)
Inside async method.
Async method completed.
                

Returning Values from Async Methods

Async methods can return values. To do this, you use the Task<T> return type. Here is an example where the async method returns an integer value:

using System;
using System.Threading.Tasks;

class Program
{
    static async Task Main(string[] args)
    {
        int result = await GetNumberAsync();
        Console.WriteLine($"Result: {result}");
    }

    static async Task<int> GetNumberAsync()
    {
        await Task.Delay(1000); // Simulate a delay
        return 42;
    }
}
Result: 42
                

Handling Exceptions in Async Methods

Exceptions in async methods can be handled using try-catch blocks. Here is an example:

using System;
using System.Threading.Tasks;

class Program
{
    static async Task Main(string[] args)
    {
        try
        {
            await ThrowExceptionAsync();
        }
        catch (Exception ex)
        {
            Console.WriteLine($"Caught exception: {ex.Message}");
        }
    }

    static async Task ThrowExceptionAsync()
    {
        await Task.Delay(500); // Simulate a delay
        throw new InvalidOperationException("Something went wrong!");
    }
}
Caught exception: Something went wrong!
                

Best Practices

Here are some best practices to consider when using async and await in C#:

  • Avoid using async void methods as they are difficult to test and debug.
  • Use async Task or async Task<T> return types for async methods.
  • Always handle exceptions in async methods.
  • Avoid blocking calls like Task.Wait() or Task.Result in async methods.
  • Keep async methods as lightweight as possible.

Conclusion

Async and await provide a powerful and easy-to-use framework for handling asynchronous operations in C#. By following best practices and understanding the core concepts, you can write more responsive and efficient code.