Async Await and Parallelism

In C#, async and await was first introduced in C# 5  detail explanation in MS Docs. You should go ahead and read those full articles. Starting from MVC 4, the async controller was introduced with async/await. Since then developers have been using async/await whenever possible.

What if a senior developer being asked: Hey explain async/await for juniors. We think we know something is just step 1. And that understanding might be wrong until we can explain to someone else.

Some believe that having asynchronous operations will make the system faster because more threads are used. Some say async will not block the main thread allowing better responsiveness of Windows Applications, or serving more requests in a Web Application.

How could we explain them? Not so many people have deep knowledge to dig deep in the low level implementation. Given that someone can (yes there are many of them), it is not easy to explain to others. Where is the balance? How about mapping the complex concept with something familiar?

I am not discussing the performance part, or will it be faster than sync. That is a complex topic and depending on many factors. Let’s analyze the serving more requests in a Web Application part.

Here is the truth, if you are in doubt ask Google

Async controller actions will allow a web application serves more requests.

Welcome to the Visa Department! You are here to get your Visa to US. There are 3 people in the department: Bob, John, and Lisa. Everyday there are hundreds of citizens come.

An applicant comes, Bob takes it. He does all the steps defined in the process. He might finish and come back 3 hours later. An applicant is solved and returned to the client.

When Bob is busy, John and Lisa take the next applicants and the process repeats. If Bob, John, and Lisa have not finished their applicants, there are just 3 applicants served. The rest has to wait.

There are 3 applicants served. The rest has to wait.

That is ASP.NET MVC synchronous controller in action. It blocks the processing pipeline.

The three decide to make a change. They organize their work and responsibilities

  1. Bob: Take incoming applicants. Put them on the boxes (labeled Requests Box) on tables next to him.
  2. John, Lisa: Take applicants in the boxes, proceed them. When an applicant is proceeded, put it in other boxes (labeled Responses Box) in the department.
  3. Whenever there is an applicant in the Responses Box, whoever (Bob, John, or Lisa) is free, take the applicant and return to the client.

What have changed in this model?

  1. Bob can take as many applicants as he can. Many clients are served.They can return to their seat, take a coffee and wait for the result.
  2. John and Lisa can coordinate or utilize the resources they have to finish the job.
  3. Anyone can return the result. Bob receives the applicant but maybe Lisa returns the result.

Is it faster to proceed one applicant? We do not know.

Can we serve many clients (applicants) in a day? Yes, definitely!

That is the ASP.NET MVC async controller in action.

Concept mapping

  1. Citizen (visa application): Request
  2. Visa Department: Web Server hosts the application.
  3. Bob, John, and Lisa: Thread
  4. Proceed an applicant: Application domain logic.
  5. Accept an applicant: Controller Action.

 

Ok Cool! Let’s see some code.

    public class ThreadModel
    {
        public int Id { get; set; }
        public string Message { get; set; }
    }
    public class ThreadTestController : Controller
    {
        [HttpGet]
        public async Task<ActionResult> Info()
        {
            var stopwatch = new Stopwatch();
            stopwatch.Start();
            var model = new List<ThreadModel>();
            model.Add(new ThreadModel
            {
                Id = Thread.CurrentThread.ManagedThreadId,
                Message = "Bob receives a visa applicant"
            });
            await Task.Delay(TimeSpan.FromSeconds(30));
            stopwatch.Stop();
            model.Add(new ThreadModel
            {
                Id = Thread.CurrentThread.ManagedThreadId,
                Message = $"Lisa returns the applicant after: {stopwatch.Elapsed}"
            });
            return Json(model);
        }
    }

And the outcome

[{"id":3,"message":"Bob receives a visa applicant"},
{"id":25,"message":"Lisa returns the applicant after: 00:00:30.0024240"}]

The request is handled at the thread 3 (Bob). And the response is handled at the thread 25 (Lisa). The elapsed time is 30 seconds.

Ok, then let’s see how long would it take if we await twice

    public class ThreadModel
    {
        public int Id { get; set; }
        public string Message { get; set; }
    }
    public class ThreadTestController : Controller
    {
        [HttpGet]
        public async Task<ActionResult> Info()
        {
            var stopwatch = new Stopwatch();
            stopwatch.Start();
            var model = new List<ThreadModel>();
            model.Add(new ThreadModel
            {
                Id = Thread.CurrentThread.ManagedThreadId,
                Message = "Bob receives a visa applicant"
            });
            await Task.Delay(TimeSpan.FromSeconds(30));
            await Task.Delay(TimeSpan.FromSeconds(30));
            stopwatch.Stop();
            model.Add(new ThreadModel
            {
                Id = Thread.CurrentThread.ManagedThreadId,
                Message = $"Lisa returns the applicant after: {stopwatch.Elapsed}"
            });
            return Json(model);
        }
    }

And the result

[{"id":29,"message":"Bob receives a visa applicant"},
{"id":32,"message":"Lisa returns the applicant after: 00:01:00.0099118"}]

It is 1 minute. Can we make it faster? How about this?

   public class ThreadTestController : Controller
    {
        [HttpGet]
        public async Task<ActionResult> Info()
        {
            var stopwatch = new Stopwatch();
            stopwatch.Start();
            var model = new List<ThreadModel>();
            model.Add(new ThreadModel
            {
                Id = Thread.CurrentThread.ManagedThreadId,
                Message = "Bob receives a visa applicant"
            });
            var t1 = Task.Delay(TimeSpan.FromSeconds(30));
            var t2 = Task.Delay(TimeSpan.FromSeconds(30));
            await Task.WhenAll(t1, t2);
            stopwatch.Stop();
            model.Add(new ThreadModel
            {
                Id = Thread.CurrentThread.ManagedThreadId,
                Message = $"Lisa returns the applicant after: {stopwatch.Elapsed}"
            });
            return Json(model);
        }
    }

Hey, look

[{"id":4,"message":"Bob receives a visa applicant"},
{"id":27,"message":"Lisa returns the applicant after: 00:00:30.0134799"}]

It is 30 seconds.

 

Asynchronous programming is a hard job. A proper understanding is very important. You do not understand unless you can explain.

Parallel Programming – get started

I have been coding for 5 years; mostly in web-based applications. And i work on serial programming; sometimes with a bit parallel: asynchronous model. Honestly speaking, my experience with multithreaded, parallel is zero. Which is bad 🙁 I know for sure what the multi threading programming is; in a basic level of awareness. That is quite a poor story of 5 year-experienced  developer.

For the past couple of days; maybe a week; i decided to take a deeper look at the topic: Multi threading, parallel programming. Having googling “Multi threading, parallel programming Google gave me thousands of links. Picked up some, read some on MSDN. And i got loss 🙁 I found some links about parallel programming in new .NET 4.0. There are books about it. Reading one of them, and again i got loss twice 🙁

OK then i realized that i had no basic knowledge about it. So how can i read  the API in .NET 4.0? Impossible! Even though i can use them, i cannot get them in mind. I decided: back to the basic. I got this book: Art of Concurrency. I scheduled for a future post about the review of the book. At first impression, it is really useful.

Here is my approach for overcoming Parallel Programming:

  1. Acknowledge the basic: by finishing the Art of Concurrency book.
  2. How it is implemented before the .NET 4.0: ask Google again.
  3. .NET 4.0: Patterns of Parallel Programming book.
  4. Write some code along the way of course.

As many other programming tools, techniques, what i really care about are:

  1. What is it?
  2. When to apply it?
  3. How to do it?
  4. How to test it? Usually unit test at first step
  5. How to debug it? Of course in case of bug.
  6. How to measure its performance comparing to the serial one?

Updated:

A sort comment about the Art of Concurrency. Honestly i cannot finish the book all 🙁 There are so many useful theories and examples. However my purpose is to get the idea of the Concurrency, Parallel. The first 4 chapters satisfy my needs. For me it is enough to move on with specific code in .NET framework.