CSharp parallel programming


C# like javascript uses async
and await
calls more or less in a similar way but not always. JS have Promises
to back it and the then
with catch
as well reducing or all together replacing the traditional try - catch
way.
Like me, most of all must of them must have stumbled in a situation where one must have witnessed using the SomeMethodAsync()
with await
keyword like var res = await SomeMethodAsync()
.
What is actually going on?
Here, let's say for the sake of brewity this call is made in the main()
or in Program.cs
file. The main()
in this case is synchronous, meaning when the program is run like ./a.out
, only one thread is running. When the await SomeMethodAsync()
is called although the SomeMethodAsync
is asynchronous, it will block the execution of that one thread until it is completed.
How to parallel program?
In C#, one way of parallel programming is through the use of Tasks
which is more less a method itself.
Now, let me elaborate the SomeMethodAsync()
as a task like below in a class.
public static class SomeClass{
async static Task SomeMethodAsync() {
Console.WriteLine("In SomeMethodAsync now.");
System.Threading.Thread.Sleep(3000);
}
}
PS - Ignore the async
warning for now.
In Program.cs
or in main
we can call it like below.
SomeClass.SomeMethodAsync();
Console.WriteLine("In main now.");
Now, first the In main now.
gets printed and then after a while the In SomeMethodAsync now.
gets printed as we did not wait for the SomeMethodAsync
to complete. In this case the call to SomeMethodAsync
forked to a new thread
.
Now let's await
for the call to complete.
await SomeClass.SomeMethodAsync();
Console.WriteLine("In main now.");
If you now run, you can see that after a while the In SomeMethodAsync now.
gets printed first and then the In main now.
since we waited for the call to complete.
In case we did not use the Task
type, the call to SomeMethodAsync
will not have forked to a new thread at all.
Use Cases
Now, since we have the gist of it, where can this benefit in our programming path. One persistent use case is with API
development where the api needs to respond to the say an http
request in a timely manner. Let's say the api is implemented in a Controller
which itself is an async task. One could send the 202 Accepted
response to the user with a unique processing id
for the request, saying that the call was received with capturing the input(s) if any like the parameters or json. Perform the relevant operation on the server. Expose another say GET
api call for the user to be able to check the status of the call with the respective processing id
.