Yaser Al-Najjar
Posted on March 18, 2019
Why even asynchronous programming?
Non-blocking code... period!
That's the whole goal of async code, you wanna write an app that doesn't hang on the user's face so that he won't feel things are stuck!
Sample for blocking ui:
src:https://www.mithunvp.com/building-responsive-ui-using-async-await-csharp/
The same app when it's doing its job the async way
src:https://www.mithunvp.com/building-responsive-ui-using-async-await-csharp/
This goes on any platform and any device, whether phone, web, or even TV apps.
So what did C# bring exactly?
The problem with async programming is that it's been always hard as you know, in C/C++ it's really hard to get it done right (and testing is even harder).
On the other hand C# brought a simple way (when Anders Hejlsberg introduced async keyword) to do that that in a much less error-prone way.
Sample code for summing numbers asynchronously:
// Code sample from: https://www.dotnetperls.com/async
using System;
using System.Threading.Tasks;
class Program
{
static void Main()
{
// Call async method 10 times.
for (int i = 0; i < 10; i++)
{
Run2Methods(i);
}
// The calls are all asynchronous, so they can end at any time.
Console.ReadLine();
}
static async void Run2Methods(int count)
{
// Run a Task that calls a method, then calls another method with ContinueWith.
int result = await Task.Run(() => GetSum(count))
.ContinueWith(task => MultiplyNegative1(task));
Console.WriteLine("Run2Methods result: " + result);
}
static int GetSum(int count)
{
// This method is called first, and returns an int.
int sum = 0;
for (int z = 0; z < count; z++)
{
sum += (int)Math.Pow(z, 2);
}
return sum;
}
static int MultiplyNegative1(Task<int> task)
{
// This method is called second, and returns a negative int.
return task.Result * -1;
}
}
You see how simple they made it, just add async await everywhere and it's gonna be magically asynchronous.
Nothing comes perfect at first
Of course, C# dudes didn't have this simple idea of async programming upfront; it's been actually developed tons of times, you can see the legacy patterns here:
https://docs.microsoft.com/en-us/dotnet/standard/async
The way other programming langs are doing it
I believe that most langs implementations are poor in doing async programming.
I mentioned the phrase "langs implementations" cuz most languages actually support async programming, but it gets tricky when implemented.
Java, Python, and even Javascript are supporting simple syntax as a "language".
Example in python
async def get_json(client, url):
async with client.get(url) as response:
assert response.status == 200
return await response.read()
The async
and await
keywords have been added after C# as mentioned in PEP492
The Java way
When I was doing Android programming, threading was the normal way to do it:
// src: https://android.jlelse.eu/8-ways-to-do-asynchronous-processing-in-android-and-counting-f634dc6fae4e
new Thread(new Runnable(){
public void run() {
// do something here
}
}).start();
But now there is CompletableFuture and AsyncTask, and Kotlin emphasize on coroutines (correct me if I'm wrong).
Other langs
Go actually follows a similar model to coroutine, but in its own Goroutines.
Javascript has the exact same syntax as C#.
As for C++, wiki mentions:
In C++, await (named co_await in C++) has been officially merged into C++20 draft
The crux of the matter
This is the reason I'm writing this post, the original question goes here:
why do you think its async support is better in C# than other programming languages?
I'm gonna tell you how it's better in one word: the adoption.
Yes, you heard that right...
Whether it's a simple HTTPClient:
// src: https://stackoverflow.com/a/31102831/4565520
public Task<string> TestDownloadTask()
{
using (HttpClient client = new HttpClient())
{
client.BaseAddress = new Uri(@"https://api.nasa.gov/planetary/apod");
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
// You don't need await here
return client.GetStringAsync("?concept_tags=True&api_key=DEMO_KEY");
}
}
A Controller in your webapp:
[HttpGet("{id}")]
public async Task<IActionResult> GetDepartment(int id){
var department = await departmentRepository.GetByIdAsync(id);
return Ok(department);
}
Or even an ORM that talks to a database (EntityFramework with linq-to-sql):
return await db.students.Where(s=>s.Name.StartsWith("A")).ToListAsync();
I've heard once famous C# author, Scott Allen, saying:
I hope we will see a day where we won't write async/await, cuz everything are just asynchronous... but it's just a hope!
Merely, cuz C# adopts async await in almost every class especially with .NET Core.
So, you will end up with mostly high performant app on every platform... if done right 😉
Know your tools well
Guess what, the async/await pattern is NOT a solution for all your asynchronous problems.
And, it's not black and white, you should understand how async/await works and also understand the costs of it.
You can achieve non-blockingness in various ways, and an event driven architecture (with a message queue fire and forget style) might help you more than relying on just adding async/await all over your code.
What do you think
Is C# doing it right? or are there much better alternatives to get a non-blocking code?
Posted on March 18, 2019
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.