When a request sent to asp.net application A thread is created to handle the request. When a thread is created, some resources such as memory are allocated to the thread. Finally, when the job is done, Garbage Collector destroys the object created for the thread. The thread life cycle is as follows:
- The request will be sent
- The Thread object is created
- Resources such as memory are allocated to the thread.
- The work is done
- Garbage Collector removes occupied space
This is done over and over again, which means that a new thread is created for each request and takes up some resources. If requests increase, many threads will be created, and if the number of threads increases, the system will slow down due to memory allocation.
But how the Thread pool works is a little different:
Thread pool is a set of threads that can be reused. That is, when a request is sent, the thread pool is first checked to see if there is a thread that is free. If available, it receives a Thread from the Thread pool and does the job, and when the job is done by the Thread, the Thread is returned to the Thread pool so that it can be used again. This feature prevents multiple threads and consumes less memory. But if no thread is available in the Thread pool, the required tasks will be queued to provide the Thread.
The main purpose of the Thread pool is to prevent the creation of many threads for small and short-term tasks.
Another important theme is Thread.Sleep and Task.Delay. Task.Delay was created for async code. When you use Thread.Sleep, the current thread is blocked (depending on the amount of time given) and this thread cannot be used elsewhere.
Normally, code written in async is executed on the Thread pool and Thread.Sleep should not be used in async code at all because it will reduce system performance because it blocks the current thread and does not allow any other work while it can Use this thread to do something else and they practically destroy the benefits of the thread pool.
If you want your method to get the Thread from the Thread pool you can use Task.Run or ThreadPool.QueueUserWorkItem. Both of these commands receive a Thread from the Thread pool.
Another difference between the default thread and the thread received from the thread pool is that the threads run in the thread pool by default in the background. That is, when the main threads that were executed in the foreground are terminated, the threads received from the thread pool also terminate and do not continue to work. But threads that run in the foreground, if it is a thread that works in the foreground, the program will not end until this thread is finished.
In the following code, in the first step, because the DoSomething method is executed by the Thread pool and works in the background by default, the program is stopped before the DoSomething method is finished.
public static void Main()
{
// Queue the task.
ThreadPool.QueueUserWorkItem(DoSomething);
Console.WriteLine("Main thread does some work, then sleeps.");
Console.WriteLine("Main thread exits.");
}
static void DoSomething(Object stateInfor)
{
Thread.Sleep(5000);
Console.WriteLine("Hello from the thread pool.");
}
The output is as follows:
Main thread does some work, then sleeps.
Main thread exits.
C:\Program Files\dotnet\dotnet.exe (process 10396) exited with code 0.
Press any key to close this window . . .
Because the DoSomething method runs in the background, the main thread of the program does not wait for the thread that does the DoSomething method to finish and the program terminates. But if we set the IsBackground property of the thread that does the DoSomething method to false, the main thread of the program will wait for the DoSomething method to finish, then the program will end.
public static void Main()
{
// Queue the task.
ThreadPool.QueueUserWorkItem(DoSomething);
Console.WriteLine("Main thread does some work, then sleeps.");
Console.WriteLine("Main thread exits.");
}
static void DoSomething(Object stateInfor)
{
Thread.CurrentThread.IsBackground = false;
Thread.Sleep(5000);
Console.WriteLine("Hello from the thread pool.");
}
And you get the following output:
Main thread does some work, then sleeps.
Main thread exits.
Hello from the thread pool.
C:\Program Files\dotnet\dotnet.exe (process 7640) exited with code 0.
Press any key to close this window . . .
Also, if you want to know whether the current thread is received from the thread pool or not, you can use the following code:
Thread.CurrentThread.IsThreadPoolThread;
You can use the following code to specify whether the thread runs in the foreground or background:
bool isBackgroundThread = Thread.CurrentThread.IsBackground;
List of sources:
- https://jonskeet.uk/csharp/threads/threadpool.html
- https://docs.microsoft.com/en-us/dotnet/standard/threading/the-managed-thread-pool
- https://dotnettutorials.net/lesson/thread-pooling/
- https://docs.microsoft.com/en-us/dotnet/api/system.threading.threadpool?view=net-5.0
- https://docs.microsoft.com/en-us/dotnet/standard/parallel-programming/task-based-asynchronous-programming
;)
Powered by Froala Editor