C# 7 and .NET Core 2.0 High Performance
上QQ阅读APP看书,第一时间看更新

Multithreading versus asynchronous programming

Multithreading and asynchronous programming, if properly implemented, improve the performance of an application. Multithreading refers to the practice of executing multiple threads at the same time to execute multiple operations or tasks in parallel. There could be one main thread and several background threads, usually known as worker threads, running in parallel at the same time, executing multiple tasks concurrently, whereas both synchronous and asynchronous operations can run on a single-threaded or a multithreaded environment.

In a single-threaded synchronous operation, there is only one thread that performs all the tasks in a defined sequence, and it executes them one after the other. In a single-threaded asynchronous operation, there is only one thread that executes the tasks, but it allocates a time slice in which to run each task. When the time slice is over, it saves the state of that task and starts executing the next one. Internally, the processor performs the context switching between each task and allocates a time slice in which to run them. 

In a multithreaded synchronous operation, there are multiple threads that run the tasks in parallel. There is no context switching between the tasks, like we have in an asynchronous operation. One thread is responsible for executing the tasks assigned to it and then starting another task, whereas in a multithreaded asynchronous operation, multiple threads run multiple tasks and the task can be served and executed by single or multiple threads.

The following diagram depicts the differences between the single and multithreaded synchronous and asynchronous operations: 

The preceding diagram shows four types of operations. In the single-threaded synchronous operation, we have one thread running five tasks sequentially. Once Task 1 is completed, Task 2 is executed, and so on. In the single-threaded asynchronous operation, we have a single thread, but each task will get a time slice to execute before the next task is executed and so on. Each task will be executed multiple times and resume from where it was paused. In the multi-threaded synchronous operation, we have three threads running three tasks Task 1, Task 2, and Task 3 in parallel. Lastly, in the multithreaded asynchronous operation, we have three tasks—Task 1, Task 2, and Task 3—running by three threads, but each thread performs some context switching based on the time slice allocated to each task. 

In asynchronous programming, it is not always the case that each asynchronous operation will be running on a new thread. Async/Await is a good example of a situation where there is no additional thread created. The async operation is executed in the current synchronization context of the main thread and queues the asynchronous operation executed in the allocated time slice.