EN VI

Is there a simple example of benefits of async await in C#?

2024-03-12 18:00:15
Is there a simple example of benefits of async await in C#?

Right now, I cannot understand the difference between async and sync code execution in an API. I'd like to see an example of async await usage in C#, that would clearly show me why it's good.

I've tried to create a simple Console App project, that would simulate an API call.

using System.Threading.Tasks;


namespace TestAppConsole
{
    internal class Program
    {
        public static async Task Main()
        {
            var asyncProcessor = new AsyncDataProcessor();
            await asyncProcessor.ProcessDataAsync();
        }
    }
}

using System;
using System.Threading.Tasks;

namespace TestAppConsole
{
    public class AsyncDataProcessor
    {
        public async Task ProcessDataAsync()
        {
            var api1Data = await GetDataFromApi1Async();
            var api2Data = await GetDataFromApi2Async();
            
            var result = Process(api1Data, api2Data);
            
            Console.WriteLine(result);
        }

        private async Task<string> GetDataFromApi1Async()
        {
            // Simulate an asynchronous API call
            await Task.Delay(2000);
            return "Data from API 1";
        }

        private async Task<string> GetDataFromApi2Async()
        {
            // Simulate another asynchronous API call
            await Task.Delay(2000);
            return "Data from API 2";
        }

        private string Process(string data1, string data2)
        {
            // Simulate data processing
            return $"Processed: {data1} and {data2}";
        }
    }
}

I thought that execution would take around 2s, but it still takes 4s, as in sync code.

Explain to me, please, how can I see the difference between async and sync code in WebAPI? Or what I've done wrong in my example, so it runs sync instead of async?

Solution:

You're currently waiting for GetDataFromApi1Async to complete before you call GetDataFromApi2Async. If you were to call both methods and then await the returned tasks, you'd see them run in parallel. For example:

public async Task ProcessDataAsync()
{
    // Somewhat dangerous - see notes below
    var api1Task = GetDataFromApi1Async();
    var api2Task = GetDataFromApi2Async();

    var api1Data = await api1Task;
    var api2Data = await api2Task;

    var result = Process(api1Data, api2Data);
    
    Console.WriteLine(result);
}

Now, this does have a problem - if both api1Task and api2Task end up faulted, you'll never see the api2Task failure. There are various ways of addressing that, but they're outside the scope of what you were asking.

There's much more to async than being able to have multiple calls in parallel though. That can be done with "normal" threading too. Async generally allows you to write that code more simply - but there are some complex aspects like the one above to be aware of. Asynchrony allows you to create a lot of asynchronous tasks without tying up threads, which a) allows a higher degree of parallelism without using that many threads; b) allows much simpler IO-based code for thread-sensitive scenarios such as WPF/WinForms user interfaces.

Answer

Login


Forgot Your Password?

Create Account


Lost your password? Please enter your email address. You will receive a link to create a new password.

Reset Password

Back to login