Threadpool Not Starting New Thread Instantly

ThreadPool not starting new Thread instantly

The ThreadPool is specifically not intended for long-running items (more specifically, you aren't even necessarily starting up new threads when you use the ThreadPool, as its purpose is to spread the tasks over a limited number of threads).

If your task is long running, you should either break it up into logical sections that are put on the ThreadPool (or use the new Task framework), or spin up your own Thread object.

As to why you're experiencing the delay, the MSDN Documentation for the ThreadPool class says the following:

As part of its thread management strategy, the thread pool delays before creating threads. Therefore, when a number of tasks are queued in a short period of time, there can be a significant delay before all the tasks are started.

You only know that the ThreadPool hasn't reached its maximum thread count, not how many threads (if any) it actually has sitting idle.

why my threadpool 's threads do not finish at same time

The threads are not being started at the same time in your example. Add the following call right after SetMaxThreads

ThreadPool.SetMinThreads(200, 200);

This will make threads start simultaneously. It's something about ThreadPool threads creating mechanics. I recommend to read ThreadPool documentation for details.

To debug it more properly, update your ThreadWhichWillCallSQL_test method to add start time too:

    static void ThreadWhichWillCallSQL_test(object o1)
{
Console.WriteLine("start:" + DateTime.Now);
Thread.Sleep(5000);
Console.WriteLine("finish: " + DateTime.Now);
}

Doesn't ThreadPoolExecutor start a new thread before the last thread is finished

You don't tell the executor to run the method, you're executing yourself.

executor.submit(t.run("gg"))

This will evaluate t.run("gg") - i.e execute the function, before it is even submitted.

You need to tell the executor what to execute, but not execute it:

executor.submit(t.run, ("gg",))

Here I'm telling it to do t.run with the arguments ("gg",)

Which results in:

start the id:  0
Task Executed <Thread(ThreadPoolExecutor-0_0, started 123145503694848)>
0 -> ('gg',)

start the id: 1
Task Executed <Thread(ThreadPoolExecutor-0_1, started 123145520484352)>
1 -> ('gg',)
...

Force ThreadPool to start the thread sooner

First off, QueueUserWorkItem doesn't create a thread, it merely places a "task" in the ThreadPool's queue for the workers to pick up and execute. In case of saturation (more tasks than available threads), there is no guarantee of when a worker will become available to execute the task. If you want immediate execution use an instance of Thread instead. The only way to improve your odds with the ThreadPool is to increase the number of workers.

Edit: Just to be clear, if thread pool threads are indeed free, they will pick up work and execute it usually faster than starting a fresh thread.

Fixed Thread Pool is exiting immediately, not processing threads

exec.shutdown() doesn't block main thread. If you need to wait for all submitted tasks to finish you need to call exec.awaitTermination(1, TimeUnit.HOUR); (of course with timeout that makes sense for your application) after call to exec.shutdown();.

/**
* Blocks until all tasks have completed execution after a shutdown
* request, or the timeout occurs, or the current thread is
* interrupted, whichever happens first.
*/
boolean awaitTermination(long timeout, TimeUnit unit)
throws InterruptedException;

Run a new thread immediately

The simplest way is to just instantiate a Thread

Thread task = new Thread(()=>
{
try
{
ConnectToCodeManager();

string connectionString = ConfigurationManager.ConnectionStrings["DataBaseConnection"].ConnectionString;

SQLTrazabilidadStorage storage = new SQLTrazabilidadStorage(connectionString);

storage.SendAggregation(parentCode, codesManagerURL);
}
catch (Exception ex)
{
log.Error(string.Format("SendAggregation to TrzCodesManagerWS: {0}", ex.ToString()));
}
});
task.Start();

Does Task.Run(Action) Start a new Thread id there are no more threads in the ThreadPool?

would Task.Run start a new Thread if there are none available in the ThreadPool?

Not immediately. The Task would be queued.

But the ThreadPool does manage its threads: when the queue fills up it will create new worker threads at a rate of 2 per second.

And when the queue runs empty Threads will be destroyed at the same rate.

The actual algorithm is a little more involved (from .NET 4 on) but it does mean that the Pool does exercise some relatively simple resource management.

Why does thread pool takes tasks independenty and not concurrently?

Why not concurrently? Why not just time-slice those 10 tasks?

You can have a thread pool that is able to perform ten concurrent tasks. You just need to configure it to have at least ten worker threads. "Time-slicing" tasks is what threads do. What thread pools do is:

  • Allow your program to control the number of threads that it uses to perform "background" tasks, and
  • Allow your program to re-use threads, which can be much more efficient than creating a new thread for each new task, and then destroying the thread when the task is complete.


Related Topics



Leave a reply



Submit