DEV Community

Cover image for Parallel Programming & Async/Await & Cancellation Token
Mo
Mo

Posted on

Parallel Programming & Async/Await & Cancellation Token


Welcome back to your favourite coding corner! Today, we're diving deep into some fascinating and crucial topics in C# programming: Parallel Programming, Async/Await, and Cancellation Tokens. These concepts are pivotal for writing efficient, responsive, and user-friendly applications. So, grab a cuppa, and let's get started! ☕️

Parallel Programming 🧵

Imagine you’ve got a bunch of tasks like downloading files, processing data, or perhaps just making a few cups of tea. Instead of doing these tasks one by one, why not do them all at once? That’s the magic of Parallel Programming.

Why Parallel Programming?

Parallel Programming allows your application to perform multiple operations simultaneously, significantly speeding up the process. This is particularly useful when dealing with CPU-bound tasks—operations that require heavy computation. By leveraging multiple CPU cores, your application can handle more work in less time.

How Does It Work? 🤔

Let’s say you have a CPU with two cores. With Parallel Programming, you can carry out two processes simultaneously. Within each process, different tasks or operations can run concurrently as needed.

But what if you only have a single-core CPU? This is where synchronous and asynchronous programming come into play.

  • Synchronous Programming: The application becomes unresponsive while waiting for an operation to complete. This is like making one cup of tea at a time—you can't start the next one until the first is done.

  • Asynchronous Programming: The application releases the thread while waiting for an operation, allowing other tasks to proceed. This is like starting a cup of tea, then moving on to start another while the first one steeps.

Here’s a quick example of Parallel.ForEach in action:

Parallel.ForEach(tasks, task =>
{
    ProcessTask(task);
});
Enter fullscreen mode Exit fullscreen mode

This simple snippet allows you to process each task concurrently, utilizing multiple cores efficiently.

Async/Await – The Smoother Way to Async Programming 🛤

Async/Await is a game changer introduced by Microsoft to simplify asynchronous programming. It helps in running tasks asynchronously without blocking the main thread, making your code more readable and manageable.

The Old Way: Callbacks

Before Async/Await, asynchronous programming was often managed using callbacks, which could make the code harder to follow. For instance, you’d need to define a callback function that triggers when an operation completes, which often led to the dreaded “callback hell”.

public class Program
{
    public static void Main()
    {
        var awaiter = DoWork().GetAwaiter();

        awaiter.OnCompleted(() =>
        {
            Console.WriteLine("Work is done!");
        });
    }

    static Task DoWork()
    {
        Task.Delay(TimeSpan.FromSeconds(3));

        return Task.CompletedTask;
    }
}
Enter fullscreen mode Exit fullscreen mode

The New Way: Async/Await ✨

With Async/Await, you can write asynchronous code that reads just like synchronous code:

public async Task DoWorkAsync()
{
    await Task.Delay(3000); // Simulate a 3-second delay
    Console.WriteLine("Work is done!");
}
Enter fullscreen mode Exit fullscreen mode

In this example, the await keyword tells the method to wait until the task completes before proceeding. This way, the main thread remains responsive, and the code is much easier to read and maintain.

What’s Happening Behind the Scenes? 🎭

Behind the scenes, the compiler transforms your async methods into state machines, implementing the IAsyncStateMachine interface. This allows the method to pause and resume execution seamlessly, managing the complexity for you. Isn’t that neat?

Cancellation Tokens – Gracefully Stopping Tasks ✋

Imagine you’re running a long process, and suddenly the user cancels it. Without proper handling, the server might continue to run these tasks, wasting valuable resources. This is where Cancellation Tokens come into play.

How It Works

A Cancellation Token is a mechanism that allows you to terminate an ongoing task gracefully. It’s like having a stop button that you can press to cancel an operation when it’s no longer needed.

Here’s how you can use it in C#:

public class Program
{
    public static async Task Main()
    {
        CancellationTokenSource cts = new();

        await cts.CancelAsync();

        await DoWork(cts.Token);
    }

    static async Task DoWork(CancellationToken token)
    {
        try
        {
            await Task.Delay(TimeSpan.FromSeconds(3), token);
        }
        catch (OperationCanceledException e)
        {
            Console.WriteLine(e);

            throw;
        }

        Console.WriteLine("Work is done!");
    }
}
Enter fullscreen mode Exit fullscreen mode

In this example, the task checks periodically if a cancellation is requested. If it is, the task stops, ensuring no unnecessary work is done.

Using CancellationToken in ASP.NET 🌐

In ASP.NET, cancellation tokens can also be used to handle requests more efficiently. Consider a scenario where a request is cancelled. You can pass a cancellation token to your API methods to stop any background work associated with that request:

app.MapGet("/do-work", async (CancellationToken cancellationToken) =>
    {
        try
        {
            await Task.Delay(TimeSpan.FromSeconds(3), cancellationToken);

            Console.WriteLine("Work is done!");
        }
        catch (OperationCanceledException e)
        {
            Console.WriteLine("Work was cancelled!");
        }
    })
    .WithName("DoWork")
    .WithOpenApi();
Enter fullscreen mode Exit fullscreen mode

If the client cancels the request, the operation is stopped, preventing unnecessary resource usage.

Wrapping It Up 🎁

And that’s a wrap, folks! We’ve covered the essentials of Parallel Programming, Async/Await, and Cancellation Tokens in C#. These concepts are vital for building efficient, responsive, and resource-friendly applications.

If you found this guide helpful, don't forget to give it a thumbs up, share it with your friends, and use the hashtags #CSharp #AsyncAwait #ParallelProgramming to spread the word! Until next time, happy coding! 👩‍💻👨‍💻


Top comments (0)