When to Use Thread Pool in C#

When to use thread pool in C#?

If you have lots of logical tasks that require constant processing and you want that to be done in parallel use the pool+scheduler.

If you need to make your IO related tasks concurrently such as downloading stuff from remote servers or disk access, but need to do this say once every few minutes, then make your own threads and kill them once you're finished.

Edit: About some considerations, I use thread pools for database access, physics/simulation, AI(games), and for scripted tasks ran on virtual machines that process lots of user defined tasks.

Normally a pool consists of 2 threads per processor (so likely 4 nowadays), however you can set up the amount of threads you want, if you know how many you need.

Edit: The reason to make your own threads is because of context changes, (thats when threads need to swap in and out of the process, along with their memory). Having useless context changes, say when you aren't using your threads, just leaving them sit around as one might say, can easily half the performance of your program (say you have 3 sleeping threads and 2 active threads). Thus if those downloading threads are just waiting they're eating up tons of CPU and cooling down the cache for your real application

what's the proper way to use a ThreadPool?

ThreadPool.SetMaxThreads(5, 5)

means the number of active thread is 5 (if you have more than 5 cpu core), does not mean that the ThreadPool can only create 5 threads.
The ThreadPool maximum number of threads = CPU Core * 250.

After Thread.Sleep, the thread is inactive, so it will not affect the execution of other threads.

why use ThreadPool has advantages over thread-based approach?

ThreadPool has a limited number of reusable threads. This threads are used for tasks (e.g. Task.Run). A task that executes for a longer period of time would block a thread so that it couldn't be reused for another Task. So in order to always have enough ThreadPool threads available (e.g. for async/await, Parallel Linq etc.), you should use ThreadPool independent threads for this kind of tasks.

You do this by using the Task.Factory.StartNew(Action, TaskCreationOptions) (or any other overload that accepts a TaskCreationOptions object) and then pass in the parameter TaskCreationOptions.LongRunning. LongRunning forces a new thread that is independent from the ThreadPool.

So for all long running and IO based tasks, like reading a file or database, you are supposed to use ThreadPool independent threads by calling Task.Factory.StartNew(() => DoAction(), TaskCreationOptions.LongRunning);. You don't need new Thread(runMethod).Start() at all.

ThreadPool threads are more resource efficient since they are reusable. So when retrieving ThreadPool threads, they are already created. Creating new threads is always resource expensive. They need to be registered, call stacks must be created, locals must be copied, etc. This is why when considering performance, reusable threads are preferable choice, as long as the workload is lightweight (short running).

What is the advantage of creating a thread outside threadpool?

what advantage would I get when I create a thread outside threadpool?

The threadpool, as it name states, is a pool of threads which are allocated once and re-used throughout, in order to save the time and resources necessary to allocate a thread. The pool itself re-sizes on demand. If you queue more work than actual workers exist in the pool, it will allocate more threads in 500ms intervals, one at a time (this exists to avoid allocation of multiple threads simultaneously where existing threads may already finish executing and can serve requests). If many long running operations are performed on the thread-pool, it causes "thread starvation", meaning delegates will start getting queued and ran only once a thread frees up. That's why you'd want to avoid a large amount of threads doing lengthy work with thread-pool threads.

The Managed Thread-Pool docs also have a section on this question:

There are several scenarios in which it is appropriate to create and
manage your own threads instead of using thread pool threads:

  • You require a foreground thread.
  • You require a thread to have a particular priority.
  • 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.

For more, see:

  • Thread vs ThreadPool

  • When should I not use the ThreadPool in .Net?

  • Dedicated thread or thread-pool thread?

When should I not use the ThreadPool in .Net?

The only reason why I wouldn't use the ThreadPool for cheap multithreading is if I need to…

  1. interract with the method running (e.g., to kill it)
  2. run code on a STA thread (this happened to me)
  3. keep the thread alive after my application has died (ThreadPool threads are background threads)
  4. in case I need to change the priority of the Thread. We can not change priority of threads in ThreadPool which is by default Normal.

P.S.: The MSDN article "The Managed Thread Pool" contains a section titled, "When Not to Use Thread Pool Threads", with a very similar but slightly more complete list of possible reasons for not using the thread pool.

There are lots of reasons why you would need to skip the ThreadPool, but if you don't know them then the ThreadPool should be good enough for you.

Alternatively, look at the new Parallel Extensions Framework, which has some neat stuff in there that may suit your needs without having to use the ThreadPool.

Is my understanding of the C# threadpool correct?

The .NET thread pool will create multiple threads per core, but has heuristics to keep the number of threads as low as possible while performing the maximum amount of work.

This means if your code is CPU-bound, you may end up with a single thread per core. If your code is I/O-bound and blocks, or queues up a huge amount of work items, you may end up with many threads per core.

It's not just thread creation that is expensive: context switching between hundreds of threads takes up a lot of time that you'd rather be spent running your own code. More threads is almost never better.

C# - ThreadPool vs Tasks

The objective of the Tasks namespace is to provide a pluggable architecture to make multi-tasking applications easier to write and more flexible.

The implementation uses a TaskScheduler object to control the handling of tasks. This has virtual methods that you can override to create your own task handling. Methods include for instance

protected virtual void QueueTask(Task task)
public virtual int MaximumConcurrencyLevel

There will be a tiny overhead to using the default implementation as there's a wrapper around the .NET threads implementation, but I'd not expect it to be huge.

There is a (draft) implementation of a custom TaskScheduler that implements multiple tasks on a single thread here.

Use ThreadPool in C# within a loop and wait for all threads to finish

.NET is almost 20 years old, and has several generations of improving APIs in it.

This is trivial with the newer Task Parallel Library methods. EG

using System;
using System.Collections.Generic;
using System.Threading.Tasks;

namespace ThreadPooling
{
class Program
{
static void Main(string[] args)
{

Console.WriteLine("Enter the number of calculations to be made:");
int calculations = Convert.ToInt32(Console.ReadLine());

var tasks = new List<Task>();
for (int i = 1; i <= calculations; i++)
{
int processNum = i;
Console.WriteLine("Staring process " + processNum + "...");
var task = Task.Run(() => Process(processNum));
tasks.Add(task);
}

Task.WaitAll(tasks.ToArray());
Console.WriteLine("All calculations done.");
Console.WriteLine("\nPress any key to exit the program...");
Console.ReadKey();

}

static void Process(int name)
{
for (int i = 0; i <= 10; i++)
{
Console.WriteLine(i + " is the current number in " + name);
}
}

}
}

Would a ThreadPool or a Task be the correct thing to use for a server?

By default, the TPL will use the Thread Pool. So, either way you are using the Thread Pool. The question is just which programming model you use to access the pool. I strongly suggest TPL, as it provides a superior programming abstraction.

The threads in your example are actually not spinning (burning CPU cycles), but rather blocking on a wait handle. That is quite efficient and does not consume a thread while blocked.

UPDATE

The TaskFactory.FromAsync(...).ContinueWith(...) pattern is appropriate. For a great list of reasons, see this question.

If you are using C# 5 / .NET 4.5, you can use async/await to express your code pattern even more compactly.

http://mtaulty.com/CommunityServer/blogs/mike_taultys_blog/archive/2010/11/22/c-5-0-rise-of-the-task.aspx

Is ThreadPool worth it in this scenario?

It depends on what you mean by "a very long time" and how common that scenario is.

The MSDN topic "The Managed Thread Pool" offers good guidelines for when not to use thread pool threads:

There are several scenarios in which it is appropriate to create and manage your own threads instead of using thread pool threads:

  • You require a foreground thread.
  • You require a thread to have a particular priority.
  • 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.


Related Topics



Leave a reply



Submit