Why is .net threadpool only used for short time intervals?

I read in many places that .net Threadpool is designed to run short time intervals (maybe no more than 3 seconds). In all of these references, I did not find a specific reason why it should not be used.

Even some people said that this leads to unpleasant results if we use long-term tasks, and also lead to deadlocks.

Can someone explain this in plain English with a technical reason why we should not use the thread pool for long-running tasks?

To be specific, I would even like to give a script and want to know why ThreadPool should not be used in this script for reasonable reasons.

Scenario: I need to process several thousand user data. The user processing data is retrieved from the local database and using this information I need to connect to the API located in some other place, and the response from the API will be saved in the local database after its processing.

If someone can explain the pitfalls to me in this scenario, if I use ThreadPool with a thread limit of 20? The processing time for each user can be from 3 seconds to 1 minute (or more).

+6
multithreading c # threadpool
source share
3 answers

A threadpool should avoid a situation where the time taken to create a thread is greater than the time taken to use it. By reusing existing flows, we avoid this overhead.

The downside is that threadpool is a shared resource: if you use a thread, something else cannot. Therefore, if you have many lengthy tasks, you can get a puzzle with an empty thread, perhaps even lead to a deadlock.

Keep in mind that your application code may not be the only code that uses a thread pool ... system code also uses it a lot.

It looks like you will want to have your own producer / consumer queue with a small number of threads processing it. Alternatively, if you can talk to another service using the asynchronous API, you may find that every bit of processing on your computer will be short-lived.

+15
source share

This is due to how the thread scheduler works. It is struggling to ensure that it does not produce more pending threads than you have processor cores. It is a good idea to run more threads than cores is wasteful because Windows has a context for switching time between threads. Creating the total time needed to complete the job longer.

As soon as the TP thread completes, another one is allowed to start. Twice per second, the TP scheduler runs when threads are not completing. He cannot understand why these threads take so long to complete their work. Half a second is a lot of processor cycles, a cool billion or so. Therefore, it assumes that threads are blocked, waiting for any I / O to complete. Like a dbase request, reading a disk, trying to connect to a socket, like that.

And it allows you to start another thread. Now you have more threads, you have kernels. This is actually not a problem, if these source threads really block, they do not consume processor cycles.

You can see where this leads: if your thread runs for 3 seconds, then this creates a little trap. It delays but does not block other TP threads that are waiting to be launched. If your thread has to spend so much time because it is constantly blocked, you better create a regular thread. And if you're really curious that the thread is not delayed by the TP scheduler, you should also use Thread.

TP Scheduler has been redone in .NET 4.0. By the way, what I wrote is really true only for earlier releases. The basics still exist, it just uses a more reasonable scheduling algorithm. Feedback-based dynamic scheduling by measuring throughput. It really matters if you have many TP threads.

+2
source share

Two reasons were not affected:

  1. The threadpool protocol is used as a normal means of handling I / O callback functions, which, as a rule, should happen very soon after completing work with I / O. In general, timeliness is more important with short tasks than long but long tasks in threadpool delay notification tasks that could (and should have been) started, started and completed quickly.
  2. If a threadpool task is blocked until some other threadpool task starts, it can start a threadpool thread, thereby delaying or, in some cases, completely blocking the start of this other task (or any other).

As a rule, the presence of a thread thread receiving a lock (waiting if necessary) is not a problem. If you want one thread thread to expect another thread to release a lock, the fact that the last thread acquired the lock in the first place means that it started. On the other hand, waiting, for example, some data coming from the connection, can cause a dead end if the I / O callback routine is used to confirm the receipt of data. If too many threadpool threads expect an I / O callback to signal that data has arrived, the system may decide to defer the callback until one of the threadpool threads terminates.

+2
source share

All Articles