C# : Async - Await
Tags: csharp, backend
Published: 2023-07-10 10:07:12

## Introduction 

## Parallel programing 

Parallel programming in C# refers to the practice of executing tasks simultaneously using multiple threads or processors to achieve improved performance and efficiency. It allows the execution of multiple operations concurrently, taking advantage of modern multi-core processors.

C# provides several features and libraries to support parallel programming:

1. Async Await keywords
2. System.Threading.Tasks.Parallel
3. Task Parallel Library (TPL):
4. Parallel LINQ (PLINQ) 

## Async Await

C# 5.0 brought forth the "async" and "await" keywords. These keywords were specifically designed to simplify the process of writing asynchronous code, enabling its execution in the background while other code runs concurrently.

By marking a method as "async," it becomes capable of running in the background while other code executes. This allows for improved concurrency. Additionally, the "await" keyword can be used within an async method to signify that the method should wait for the completion of an asynchronous operation before proceeding further. This ensures proper synchronization and orderly execution of the code.

Asynchronous programming is a technique that enables concurrent code execution without blocking the calling thread. It allows code to run in the background while other operations continue. In contrast, synchronous programming executes each line sequentially, causing the program to wait for each operation to finish before moving on to the next. This can result in performance issues, especially when dealing with time-consuming tasks like I/O or network requests.

By employing asynchronous programming, programs can perform these operations without halting the calling thread. When an asynchronous operation starts, the program proceeds with other code execution while waiting for the operation to complete. The program receives a notification when the operation finishes and can proceed to the next line of code.

Asynchronous programming can be implemented using various techniques like callbacks, events, and promises. In C#, the "async" and "await" keywords offer a convenient way to write asynchronous code that resembles synchronous code, enhancing readability and maintainability.

By utilizing the "async" and "await" keywords, we can reap the benefits of traditional asynchronous programming with less effort. For instance, consider two methods, Method1 and Method2, which are independent of each other but Method1 takes a long time to complete. In synchronous programming, Method1 would execute first, followed by Method2, causing unnecessary delays even though they are not interdependent.

While parallel execution using thread programming is an option, it can block the user interface and wait for all tasks to complete. To address this issue, traditional programming often requires writing extensive code. However, the use of "async" and "await" keywords significantly simplifies the solution.

## Examples

_1, Synchronous: We download the data one by one._
![Synchronousg](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/spit9dcf34uzivtuogeq.png)

_2, Asynchronous: We create an FetchAsync() function which returns the website's length._

![Asynchronous](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cozle3kkqgj2iy7m0pkb.png)

_3, Asynchronous: Fetch with different website URLs_

![Asynchronous2](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wi660gz5jqg3hirh61af.png)

In this case the 3 Task starts right away in a different thread, and when they returned with a value it merges back, but with the await keyword, we force our Main thread to merge(callback) the new threads Tasks into the Main thread current line. So it wont continue if the task are not done.  

## System.Threading.Tasks.Parallel

Most of the time doing Parallel programing means that you are about to reduce the runtime of your application by clever logic. I mean clever logic like: your operation system already knows the best way to add a + b 1 million times, its spread the task to the CPU cores then return. But if you do something not trivial computing where you can separate the problem into different sets, then you can do the computing and merging it back much faster.

You should always stick to Parallel programing if you are doing cpu heavy computations. Otherwise just use Async Tasks.

_4, Lets reproduce our Async function with this library (Not the best example)._

![Parallel](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7619eogsf6cmohxlv69x.png)

MaxDegreeOfParallelism = 3 means how much resource(cpu core) it should use for this task.

_5, For some testing purpose I made a benchmark:_

![Benchmark](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fkaxqgrx63qm2u3br1b6.png)

Source code: https://github.com/SomAniac0/Academy/tree/main/Academy/Async