In my initial development days, I used to get confused when it came to threads, tasks, and asynchrony. Later on, I was able to understand it. In this blog, I want to give you an overview of how it works in .NET.
When you run your application or program, it executes on your machine and utilizes your machine resources like cores and memory. Multithreading allows you to increase the responsiveness of your application and, when your application runs on a multiprocessor or multi-core system, increase its throughput.
Treads & Tasks:
Process– Executing a program or application is called a process.
Thread– It is a small unit of executing a program to which the operating system allocates time. This small unit can be any part of your application.
- The process can have multiple threads run parallelly, called threading.
- A thread can execute any part of the program code, including parts currently being executed by another thread.
- Thread has an affinity with the core. Once it executes on one core, it will continue to run on the same core. The developer needs to manage the thread execution on the different cores available by checking the load on the cores.
- The foreground thread is the default thread that keeps running even if your main application exited.
- The background thread quits when the main application quits.
Thread Pool– a collection of workers’ threads that effectively runs asynchronous callbacks of the application.
When the program starts, it runs by default on a single thread called a primary thread. However, it can create additional threads to execute code in parallel or concurrently with the primary thread. These threads are often called worker threads. These threads are available in the thread pool to use.
Many developers get confused when it comes to tasks and threads. The tasks manage the threads for you internally so that optimal use of the machine resources can happen. This leads to better responsiveness and performance.
Tasks & TPL-
- It is the object that represents some work that should be done.
- It is the encapsulation over threading. It utilizes threads from the thread pool for optimal utilization of the machine resources.
- When you are using tasks and their features using TPL(Task Parallel Library), you don’t need to manage the threads at a lower level.
- Encapsulate auto multi-core execution
- Parallelism across the cores will be taken care of by TPL
Managing concurrency and parallelism:
Concurrent Tasks- Multiple tasks run on the same core with time slicing. It gives the feeling that tasks are running parallelly.
- It is all about the Non-blocking of the application
- It is more about the usability of the application
- It uses time-slicing between the tasks or context switching
- The time slicing happens between different tasks is indeterministic. The final output is deterministic.
Parallel Tasks- Multiple tasks run on different cores at the same time parallelly.
- It is all about performance only
- The tasks run on different resources/cores at the same time, which leads to performance improvement
Async & Await are code markers that mark code positions from where the control should resume after the task or thread is complete.
- It helps non-blocking in the application
- It doesn’t create a separate thread
- If the async method has awaited thread or task inside it, a call to this method can go on doing its work after the calling thread exited