Click here to Skip to main content
15,914,225 members
Articles / All Topics

Two Common Misconceptions about Multithreading and Async

Rate me:
Please Sign up or sign in to vote.
4.82/5 (15 votes)
20 Jan 2015CPOL4 min read 8.5K   9   1
Here are two common misconceptions about multithreading and Async

I’ve recently talked to several experienced developers that struggle with the async/await keywords introduced in .NET 4.5. There are literally hundreds of good articles out there on the topic; however, they continue to struggle with two misconceptions. The first is that the async keyword is just another way to do multithreading. The other is that multithreading and asynchrony are meant to improve performance. This blog post will give some history and dispel these fallacies.

Multithreading Improves Performance FALSE

I may be dating myself here, but I remember working with 16 bit Windows (when I was a young humpback freak). Back then, the OS would hand over the CPU to an application. The application completely controlled the CPU and would relinquish control once it ran to completion. The OS had no way of breaking into the application process. Therefore, fatal exceptions or infinite loops would cause the machine to become unresponsive and the only way to regain control was a reboot. In order to combat this problem, threads were introduced.

In a nutshell, a thread is a virtualization of the CPU. Threads are provisioned by the OS and scheduled to run for a quantum (slice of time). At the end of each quantum, the OS performs a context switch. A context switch consists of storing away the current state of the registers and restoring the registers for the next thread. Threads are scheduled by the OS in a round robin fashion. This is how OS can do more than one thing at a time. If an application gets caught in an infinite loop, the OS can kill it from a different thread.

The main take away concept here is that, although very efficient, new threads and context switches are not free. The more threads there are, the more context switches, and the less time each thread has on the CPU. When you introduce threading, the overall system performance goes DOWN. Threading was introduced to make the OS fault tolerant against application errors. Any time you can perform work in a single thread, that is preferred.

The most common use of multithreading is to keep an UI responsive. A UI thread needs to be available to respond to user input; therefore, work needs to be done in different threads.

Now, it’s time to make a seemingly contradictory statement: multithreading can make your programs run faster. Raw performance and overall application processing time are two different things. Today, many machines come equipped with multiple CPUs. If you have CPU bound work (see the next section), you can reduce application processing time by scheduling multiple CPUs to do work at the same time. This assumes that the OS does not have the CPUs busy doing other things…

Asynchronous Means Multithreading FALSE

Although the two concepts are somewhat related (you can do multithreading with the async/await keywords), they are very different. Asynchronous calls do pretty much the opposite of multithreading; they make a single thread do more. This is accomplished by not holding a thread hostage waiting on I/O bound work. Before we continue, let's define I/O bound verses CPU bound work.

I/O bound work – The OS makes a request to a device driver (network card, printer, hard drive, etc…). The device performs some work and returns data back to the OS.

CPU bound work – Actual processor cycles (long loops, calculations, etc…)

In reality, there is very little CPU bound work. Yes, it does exist but the majority of time intensive tasks fall into the I/O bound category.

When your application makes a request to a device driver (via the OS), it does not return data immediately. The OS sends the request to the device and then forgets about it until the device sends an interrupt indicating that it’s done. If your application is not using an asynchronous method call, the thread will just hang doing nothing while the device is doing its thing. An asynchronous method call will return the thread back to the OS so it can do other work. Once the OS receives the “I'm done” interrupt, the OS will schedule the work to resume. In this way, the OS avoids the overhead of creating new threads.

The above is an greatly simplified version of things; however, I hope it gave you enough of a conceptual understanding to enable you to use async/await in the right way. There are plenty of computer science resources out there if you want a deeper dive…

Thank you for reading! As always, feel free to hit me up with any questions.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior)
United States United States
I’m a passionate developer with more than 20 years of experience in countless different languages. Currently, I’m a senior software engineer for a research company where I specialize in full stack web development with .NET. I have extensive experience with ASP.NET, MVC, C#, Azure, JavaScript, JQuery, AngluarJS, TypeScript, NoSQL (RavenDB), and SQL Server.

Comments and Discussions

 
QuestionHad similar problems before Pin
irneb21-Jan-15 2:16
irneb21-Jan-15 2:16 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.