Tech
News
Videos
Forums
Jobs
Books
Events
More
Interviews
Live
Learn
Training
Career
Members
Blogs
Challenges
Certification
Contribute
Article
Blog
Video
Ebook
Interview Question
Collapse
Feed
Dashboard
Wallet
Learn
Achievements
Network
Rewards
SharpGPT
Premium
Contribute
Article
Blog
Video
Ebook
Interview Question
Register
Login
Thread Pool In .NET Core And C#
WhatsApp
Mahesh Chand
6y
165k
0
17
100
Article
Creation and destruction of new threads comes with a cost and it affects an application’s performance. Threads can also be blocked or go into sleep or other unresolved states. If your app doesn’t distribute the workload properly, worker threads may spend the majority of their time sleeping. This is where thread pool comes in handy.
A thread pool is a pool of worker threads that have already been created and are available for apps to use them as needed. Once thread pool threads finish executing their tasks, they go back to the pool.
.NET provides a managed thread pool via the ThreadPool class that is managed by the system. As a developer, we don’t need to deal with the thread management overhead. For any short background tasks, the managed thread pool is a better choice than creating and managing your own threads. Thread pool threads are good for background processes only and not recommended for foreground threads. There is only one thread pool per process.
Use of thread pool is not recommended when,
You need to prioritize a thread.
Thread is a foreground thread.
You have tasks that cause the thread to block for long periods of time. The thread pool has a maximum number of threads, so a large number of blocked thread pool threads might prevent tasks from starting.
You need to place threads into a single-threaded apartment. All ThreadPool threads are in the multithreaded apartment.
You need to have a stable identity associated with the thread, or to dedicate a thread to a task.
If you're new to threading, start with
Threading in C# and .NET Core
.
ThreadPool
The ThreadPool class has several static methods including the QueueUserWorkItem that is responsible for calling a thread pool worker thread when it is available. If no worker thread is available in the thread pool, it waits until the thread becomes available.
The QueueWorkItem method takes a procedure that executes in the background.
ThreadPool.QueueUserWorkItem(BackgroundTask);
Here is a complete example of how to call a worker thread from thread pool to execute a method in the background.
using
System;
using
System.Threading;
class
ThreadPoolSample
{
// Background task
static
void
BackgroundTask(Object stateInfo)
{
Console.WriteLine(
"Hello! I'm a worker from ThreadPool"
);
Thread.Sleep(1000);
}
static
void
Main(
string
[] args)
{
// Use ThreadPool for a worker thread
ThreadPool.QueueUserWorkItem(BackgroundTask);
Console.WriteLine(
"Main thread does some work, then sleeps."
);
Thread.Sleep(500);
Console.WriteLine(
"Main thread exits."
);
Console.ReadKey();
}
}
You can also pass values to a background method via the QueueWorkItem method. The second parameter of the method is an object that can be any object you would like to pass to your background procedure.
Let’s assume we have a Person class with the following members.
// Create a Person class
public
class
Person
{
public
string
Name {
get
;
set
; }
public
int
Age {
get
;
set
; }
public
string
Sex {
get
;
set
; }
public
Person(
string
name,
int
age,
string
sex)
{
this
.Name = name;
this
.Age = age;
this
.Sex = sex;
}
}
We can create an object of Person type and pass it to the QueueUserWorkItem method.
// Create an object and pass it to ThreadPool worker thread
Person p =
new
Person(
"Mahesh Chand"
, 40,
"Male"
);
ThreadPool.QueueUserWorkItem(BackgroundTaskWithObject, p);
And
in
the worker method, we can extract values from the
object
and use it. In the following example, I read back the Person.Name and displays on the console.
static
void
BackgroundTaskWithObject(Object stateInfo)
{
Person data = (Person)stateInfo;
Console.WriteLine($
"Hi {data.Name} from ThreadPool."
);
Thread.Sleep(1000);
}
The complete code is listed in the following code.
using
System;
using
System.Threading;
class
ThreadPoolSample
{
// Background task
static
void
BackgroundTask(Object stateInfo)
{
Console.WriteLine(
"Hello! I'm a worker from ThreadPool"
);
Thread.Sleep(1000);
}
static
void
BackgroundTaskWithObject(Object stateInfo)
{
Person data = (Person)stateInfo;
Console.WriteLine($
"Hi {data.Name} from ThreadPool."
);
Thread.Sleep(1000);
}
static
void
Main(
string
[] args)
{
// Create an object and pass it to ThreadPool worker thread
Person p =
new
Person(
"Mahesh Chand"
, 40,
"Male"
);
ThreadPool.QueueUserWorkItem(BackgroundTaskWithObject, p);
Console.ReadKey();
}
// Create a Person class
public
class
Person
{
public
string
Name {
get
;
set
; }
public
int
Age {
get
;
set
; }
public
string
Sex {
get
;
set
; }
public
Person(
string
name,
int
age,
string
sex)
{
this
.Name = name;
this
.Age = age;
this
.Sex = sex;
}
}
}
Maximum and Minimum Thread Pool Threads
Thread pool size is the number of threads available in a thread pool. The thread pool provides new worker threads or I/O completion threads on demand until it reaches the minimum for each category. By default, the minimum number of threads is set to the number of processors on a system. When the minimum is reached, the thread pool can create additional threads in that category or wait until some tasks complete. The thread pool creates and destroys threads to optimize throughput, which is defined as the number of tasks that complete per unit of time. Too few threads might not make optimal use of available resources, whereas too many threads could increase resource contention.
ThreadPool.GetAvailalbeThreads returns the number of threads that are available currently in a pool. It is the number of maximum threads minus currently active threads.
int
workers, ports;
// Get available threads
ThreadPool.GetAvailableThreads(
out
workers,
out
ports);
Console.WriteLine($
"Availalbe worker threads: {workers} "
);
Console.WriteLine($
"Available completion port threads: {ports}"
);
ThreadPool.GetMaxThreads and ThreadPool.GetMinThreads returns the maximum and minimum threads available in a thread pool.
int
workers, ports;
// Get maximum number of threads
ThreadPool.GetMaxThreads(
out
workers,
out
ports);
Console.WriteLine($
"Maximum worker threads: {workers} "
);
Console.WriteLine($
"Maximum completion port threads: {ports}"
);
ThreadPool.SetMaxThreads and ThreadPool.SetMinThreads are used to set maximum and minimum number of threads on demand as needed in a thread pool. By default, the minimum number of threads is set to the number of processors on a system.
int
workers, ports;
// Set minimum threads
int
minWorker, minIOC;
ThreadPool.GetMinThreads(
out
minWorker,
out
minIOC);
ThreadPool.SetMinThreads(4, minIOC);
The complete example is the following code.
using
System;
using
System.Threading;
class
ThreadPoolSample
{
// Background task
static
void
BackgroundTask(Object stateInfo)
{
Console.WriteLine(
"Hello! I'm a worker from ThreadPool"
);
Thread.Sleep(1000);
}
static
void
BackgroundTaskWithObject(Object stateInfo)
{
Person data = (Person)stateInfo;
Console.WriteLine($
"Hi {data.Name} from ThreadPool."
);
Thread.Sleep(1000);
}
static
void
Main(
string
[] args)
{
// Use ThreadPool for a worker thread
ThreadPool.QueueUserWorkItem(BackgroundTask);
Console.WriteLine(
"Main thread does some work, then sleeps."
);
Thread.Sleep(500);
// Create an object and pass it to ThreadPool worker thread
Person p =
new
Person(
"Mahesh Chand"
, 40,
"Male"
);
ThreadPool.QueueUserWorkItem(BackgroundTaskWithObject, p);
int
workers, ports;
// Get maximum number of threads
ThreadPool.GetMaxThreads(
out
workers,
out
ports);
Console.WriteLine($
"Maximum worker threads: {workers} "
);
Console.WriteLine($
"Maximum completion port threads: {ports}"
);
// Get available threads
ThreadPool.GetAvailableThreads(
out
workers,
out
ports);
Console.WriteLine($
"Availalbe worker threads: {workers} "
);
Console.WriteLine($
"Available completion port threads: {ports}"
);
// Set minimum threads
int
minWorker, minIOC;
ThreadPool.GetMinThreads(
out
minWorker,
out
minIOC);
ThreadPool.SetMinThreads(4, minIOC);
// Get total number of processes availalbe on the machine
int
processCount = Environment.ProcessorCount;
Console.WriteLine($
"No. of processes available on the system: {processCount}"
);
// Get minimum number of threads
ThreadPool.GetMinThreads(
out
workers,
out
ports);
Console.WriteLine($
"Minimum worker threads: {workers} "
);
Console.WriteLine($
"Minimum completion port threads: {ports}"
);
Console.ReadKey();
}
// Create a Person class
public
class
Person
{
public
string
Name {
get
;
set
; }
public
int
Age {
get
;
set
; }
public
string
Sex {
get
;
set
; }
public
Person(
string
name,
int
age,
string
sex)
{
this
.Name = name;
this
.Age = age;
this
.Sex = sex;
}
}
}
Summary
In this article with the code sample, we learned what a thread pool is and how to use it in .NET Core apps.
.NET Core Threading
Thread Pool
Threading
Up Next
Ebook Download
View all
Printing in C# Made Easy
Read by 22.3k people
Download Now!
Learn
View all
Mindcracker
Founded in 2003, Mindcracker is the authority in custom software development and innovation. We put best practices into action. We deliver solutions based on consumer and industry analysis.
Membership not found